摘要:本文是重溫基礎(chǔ)系列文章的第十二篇。注意對象的名稱,對大小寫敏感。基礎(chǔ)用法第一個參數(shù)是目標對象,后面參數(shù)都是源對象。用途遍歷對象屬性。用途將對象轉(zhuǎn)為真正的結(jié)構(gòu)。使用場景取出參數(shù)對象所有可遍歷屬性,拷貝到當(dāng)前對象中。類似方法合并兩個對象。
本文是 重溫基礎(chǔ) 系列文章的第十二篇。
今日感受:需要總結(jié)下2018。
這幾天,重重的感冒發(fā)燒,在家休息好幾天,傷···。
系列目錄:
【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個人整理)
【重溫基礎(chǔ)】1.語法和數(shù)據(jù)類型
【重溫基礎(chǔ)】2.流程控制和錯誤處理
【重溫基礎(chǔ)】3.循環(huán)和迭代
【重溫基礎(chǔ)】4.函數(shù)
【重溫基礎(chǔ)】5.表達式和運算符
【重溫基礎(chǔ)】6.數(shù)字
【重溫基礎(chǔ)】7.時間對象
【重溫基礎(chǔ)】8.字符串
【重溫基礎(chǔ)】9.正則表達式
【重溫基礎(chǔ)】10.數(shù)組
【重溫基礎(chǔ)】11.Map和Set對象
本章節(jié)復(fù)習(xí)的是JS中對象的使用,這是重點。
前置知識:
JavaScrip的設(shè)計是一個簡單的基于對象的范式。
對象是一系列屬性的集合,一個屬性包含一個鍵和一個值,也叫鍵值對。
若一個屬性的值,是一個函數(shù),則稱這個屬性為方法。
一個對象,可以有很多方法,就像一個杯子,可以有顏色,重量,形狀等屬性。
注意:
對象的名稱,對大小寫敏感。
本文主要是復(fù)習(xí)對象的使用,至于對象的創(chuàng)建,下面這里簡單介紹一下常見的創(chuàng)建對象的方法:
創(chuàng)建方法1:
let obj = new Object(); // 聲明一個空對象
創(chuàng)建方法2:
let obj = {}; // 聲明一個空對象
上面的name是對象obj中的一個屬性,對應(yīng)的值為"leo"。
2.設(shè)置對象屬性和訪問屬性設(shè)置對象屬性,也有兩種方法:
直接設(shè)置:
let obj = {}; obj.name = "leo"; // 為對象添加屬性和值
創(chuàng)建時設(shè)置:
let obj = {name : "leo"}; obj.name = "leo"; // 為對象添加屬性和值
當(dāng)一個對象定義了一個屬性,我們可以用點符號(.)來訪問它。
obj.name; // "leo"
注意:
屬性的另外一種寫法:
let obj = {}; let n = "name"; obj[n] = "leo"; // 屬性名使用變量 obj["height"] = 188; // 字符串 obj["age" + "Is"] = 15; // 字符串拼接 console.log(obj); /* obj = { ageIs: 15 height: 188 name: "leo" } */
屬性的值也可以是個方法:
let obj = {}; obj.getTime = function(){ return new Date(); } obj.getTime(); // 訪問屬性的方法 //Wed Jan 02 2019 21:07:59 GMT+0800 (中國標準時間)3.枚舉對象的所有屬性
從 ECMAScript 5 開始,有三種原生的方法用于列出或枚舉對象的屬性:
3.1 for...in 循環(huán)該方法依次訪問一個對象及其原型鏈中所有可枚舉的屬性。
let obj = {a:1, b:2, c:3}; for (let i in obj) { console.log("obj." + i + " = " + obj[i]); } /* "obj.a = 1" "obj.b = 2" "obj.c = 3" */3.2 Object.keys(o)
該方法返回一個對象 o 自身包含(不包括原型中)的所有屬性的名稱的數(shù)組。
let obj = {a:1, b:2, c:3}; let arr = Object.keys(obj); console.log(arr); /* ["a", "b", "c"] */ arr.forEach(function(val,index,array){ console.log("key:" + val+",val:"+obj[val]) }) /* key:a,val:1 key:b,val:2 key:c,val:3 */3.3 Object.getOwnPropertyNames(o)
該方法返回一個數(shù)組,它包含了對象 o 所有擁有的屬性(無論是否可枚舉)的名稱。
let obj = {a:1, b:2, c:3}; let arr = Object.getOwnPropertyNames(obj); console.log(arr); /* ["a", "b", "c"] */ arr.forEach(function(val,index,array){ console.log("key:" + val+",val:"+obj[val]) }) /* key:a,val:1 key:b,val:2 key:c,val:3 */4.ES6新增:對象的拓展 4.1 屬性的簡潔表示
let a = "a1"; let b = { a }; // b => { a : "a1" } // 等同于 let b = { a : a }; function f(a, b){ return {a, b}; } // 等同于 function f (a, b){ return {a:a ,b:b}; } let a = { fun () { return "leo"; } } // 等同于 let a = { fun : function(){ return "leo"; } }4.2 屬性名表達式
JavaScript提供2種方法定義對象的屬性。
// 方法1 標識符作為屬性名 a.f = true; // 方法2 字符串作為屬性名 a["f" + "un"] = true;
延伸出來的還有:
let a = "hi leo"; let b = { [a]: true, ["a"+"bc"]: 123, ["my" + "fun"] (){ return "hi"; } }; // b.a => undefined ; b.abc => 123 ; b.myfun() => "hi" // b[a] => true ; b["abc"] => 123 ; b["myfun"] => ? ["my" + "fun"] (){ return "hi"; }
注意:
屬性名表達式不能與簡潔表示法同時使用,否則報錯。
// 報錯 let a1 = "aa"; let a2 = "bb"; let b1 = {[a1]}; // 正確 let a1 = "aa"; let b1 = { [a1] : "bb"};4.3 Object.is()
Object.is() 用于比較兩個值是否嚴格相等,在ES5時候只要使用相等運算符(==)和嚴格相等運算符(===)就可以做比較,但是它們都有缺點,前者會自動轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。
Object.is("a","a"); // true Object.is({}, {}); // false // ES5 +0 === -0 ; // true NaN === NaN; // false // ES6 Object.is(+0,-0); // false Object.is(NaN,NaN); // true4.4 Object.assign()
Object.assign()方法用于對象的合并,將原對象的所有可枚舉屬性復(fù)制到目標對象。
基礎(chǔ)用法:
第一個參數(shù)是目標對象,后面參數(shù)都是源對象。
let a = {a:1}; let b = {b:2}; Object.assign(a,b); // a=> {a:1,b:2}
注意:
若目標對象與源對象有同名屬性,則后面屬性會覆蓋前面屬性。
let a = {a:1, b:2}; let b = {b:3, c:4}; Object.assign(a, b); // a => {a:1, b:3, c:4}
若只有一個參數(shù),則返回該參數(shù)。
let a = {a:1}; Object.assign(a) === a; // true
若參數(shù)不是對象,則先轉(zhuǎn)成對象后返回。
typeof Object.assign(2); // "object"
由于undefined或NaN無法轉(zhuǎn)成對象,所以做為參數(shù)會報錯。
Object.assign(undefined) // 報錯 Object.assign(NaN); // 報錯
Object.assign()實現(xiàn)的是淺拷貝。
Object.assign()拷貝得到的是這個對象的引用。這個對象的任何變化,都會反映到目標對象上面。
let a = {a: {b:1}}; let b = Object.assign({},a); a.a.b = 2; console.log(b.a.b); // 2
將數(shù)組當(dāng)做對象處理,鍵名為數(shù)組下標,鍵值為數(shù)組下標對應(yīng)的值。
Object.assign([1, 2, 3], [4, 5]); // [4, 5, 3]5.ES8新增:Object.values(),Object.entries()
ES7中新增加的 Object.values()和Object.entries()與之前的Object.keys()類似,返回數(shù)組類型。
回顧下Object.keys():
var a = { f1: "hi", f2: "leo"}; Object.keys(a); // ["f1", "f2"]5.1 Object.values()
返回一個數(shù)組,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷屬性的鍵值。
let a = { f1: "hi", f2: "leo"}; Object.values(a); // ["hi", "leo"]
如果參數(shù)不是對象,則返回空數(shù)組:
Object.values(10); // [] Object.values(true); // []5.2 Object.entries()
返回一個數(shù)組,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷屬性的鍵值對數(shù)組。
let a = { f1: "hi", f2: "leo"}; Object.entries(a); // [["f1","hi"], ["f2", "leo"]]
用途1:
遍歷對象屬性。
let a = { f1: "hi", f2: "leo"}; for (let [k, v] of Object.entries(a)){ console.log( `${JSON.stringfy(k)}:${JSON.stringfy(v)}` ) } // "f1":"hi" // "f2":"leo"
用途2:
將對象轉(zhuǎn)為真正的Map結(jié)構(gòu)。
let a = { f1: "hi", f2: "leo"}; let map = new Map(Object.entries(a));
手動實現(xiàn)Object.entries()方法:
// Generator函數(shù)實現(xiàn): function* entries(obj){ for (let k of Object.keys(obj)){ yield [k ,obj[k]]; } } // 非Generator函數(shù)實現(xiàn): function entries (obj){ let arr = []; for(let k of Object.keys(obj)){ arr.push([k, obj[k]]); } return arr; }6.ES8新增:Object.getOwnPropertyDescriptors()
之前有Object.getOwnPropertyDescriptor方法會返回某個對象屬性的描述對象,新增的Object.getOwnPropertyDescriptors()方法,返回指定對象所有自身屬性(非繼承屬性)的描述對象,所有原對象的屬性名都是該對象的屬性名,對應(yīng)的屬性值就是該屬性的描述對象
let a = { a1:1, get f1(){ return 100} } Object.getOwnPropetyDescriptors(a); /* { a:{ configurable:true, enumerable:true, value:1, writeable:true} f1:{ configurable:true, enumerable:true, get:f, set:undefined} } */
實現(xiàn)原理:
function getOwnPropertyDescriptors(obj) { const result = {}; for (let key of Reflect.ownKeys(obj)) { result[key] = Object.getOwnPropertyDescriptor(obj, key); } return result; }
引入這個方法,主要是為了解決Object.assign()無法正確拷貝get屬性和set屬性的問題。
let a = { set f(v){ console.log(v) } } let b = {}; Object.assign(b, a); Object.a(b, "f"); /* f = { configurable: true, enumable: true, value: undefined, writeable: true } */
value為undefined是因為Object.assign方法不會拷貝其中的get和set方法,使用getOwnPropertyDescriptors配合Object.defineProperties方法來實現(xiàn)正確的拷貝:
let a = { set f(v){ console.log(v) } } let b = {}; Object.defineProperties(b, Object.getOwnPropertyDescriptors(a)); Object.getOwnPropertyDescriptor(b, "f") /* configurable: true, enumable: true, get: undefined, set: function(){...} */
Object.getOwnPropertyDescriptors方法的配合Object.create方法,將對象屬性克隆到一個新對象,實現(xiàn)淺拷貝。
const clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); // 或者 const shallowClone = (obj) => Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) );7.ES9新增:對象的拓展運算符 7.1 介紹
對象的拓展運算符,即對象的Rest/Spread屬性,可將對象解構(gòu)賦值用于從一個對象取值,搜鍵值對分配到指定對象上,與數(shù)組的拓展運算符類似:
let {x, y, ...z} = {x:1, y:2, a:3, b:4}; x; // 1 y; // 2 z; // {a:3, b:4}
對象的解構(gòu)賦值要求等號右邊必須是個對象,所以如果等號右邊是undefined或null就會報錯無法轉(zhuǎn)成對象。
let {a, ...b} = null; // 運行時報錯 let {a, ...b} = undefined; // 運行時報錯
解構(gòu)賦值必須是最后一個參數(shù),否則報錯。
let {...a, b, c} = obj; // 語法錯誤 let {a, ...b, c} = obj; // 語法錯誤
注意:
1.解構(gòu)賦值是淺拷貝。
let a = {a1: {a2: "leo"}}; let {...b} = a; a.a1.a2 = "leo"; b.a1.a2 = "leo";
2.拓展運算符的解構(gòu)賦值,不能復(fù)制繼承自原型對象的屬性。
let o1 = { a: 1 }; let o2 = { b: 2 }; o2.__proto__ = o1; let { ...o3 } = o2; o3; // { b: 2 } o3.a; // undefined7.2 使用場景
1.取出參數(shù)對象所有可遍歷屬性,拷貝到當(dāng)前對象中。
let a = { a1:1, a2:2 }; let b = { ...a }; b; // { a1:1, a2:2 } // 類似Object.assign方法
2.合并兩個對象。
let a = { a1:1, a2:2 }; let b = { b1:11, b2:22 }; let ab = { ...a, ...b }; // {a1: 1, a2: 2, b1: 11, b2: 22} // 等同于 let ab = Object.assign({}, a, b);
3.將自定義屬性放在拓展運算符后面,覆蓋對象原有的同名屬性。
let a = { a1:1, a2:2, a3:3 }; let r = { ...a, a3:666 }; // r {a1: 1, a2: 2, a3: 666} // 等同于 let r = { ...a, ...{ a3:666 }}; // r {a1: 1, a2: 2, a3: 666} // 等同于 let r = Object.assign({}, a, { a3:666 }); // r {a1: 1, a2: 2, a3: 666}
4.將自定義屬性放在拓展運算符前面,就會成為設(shè)置新對象的默認值。
let a = { a1:1, a2:2 }; let r = { a3:666, ...a }; // r {a3: 666, a1: 1, a2: 2} // 等同于 let r = Object.assign({}, {a3:666}, a); // r {a3: 666, a1: 1, a2: 2} // 等同于 let r = Object.assign({a3:666}, a); // r {a3: 666, a1: 1, a2: 2}
5.拓展運算符后面可以使用表達式。
let a = { ...(x>1? {a:!:{}), b:2 }
6.拓展運算符后面如果是個空對象,則沒有任何效果。
{...{}, a:1}; // {a:1}
7.若參數(shù)是null或undefined則忽略且不報錯。
let a = { ...null, ...undefined }; // 不報錯
8.若有取值函數(shù)get則會執(zhí)行。
// 不會打印 因為f屬性只是定義 而不沒執(zhí)行 let a = { ...a1, get f(){console.log(1)} } // 會打印 因為f執(zhí)行了 let a = { ...a1, ...{ get f(){console.log(1)} } }參考資料
1.MDN 使用對象
2.W3school JavaScript 對象
本部分內(nèi)容到這結(jié)束
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推薦 | https://github.com/pingan8787... |
JS小冊 | js.pingan8787.com |
歡迎關(guān)注微信公眾號【前端自習(xí)課】每天早晨,與您一起學(xué)習(xí)一篇優(yōu)秀的前端技術(shù)博文 .
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/100632.html
摘要:本文是重溫基礎(chǔ)系列文章的第七篇。系列目錄復(fù)習(xí)資料資料整理個人整理重溫基礎(chǔ)語法和數(shù)據(jù)類型重溫基礎(chǔ)流程控制和錯誤處理重溫基礎(chǔ)循環(huán)和迭代重溫基礎(chǔ)函數(shù)重溫基礎(chǔ)表達式和運算符重溫基礎(chǔ)數(shù)字本章節(jié)復(fù)習(xí)的是中的時間對象,一些處理的方法。 本文是 重溫基礎(chǔ) 系列文章的第七篇。今日感受:做好自律。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1.語法和數(shù)據(jù)類型...
摘要:構(gòu)造函數(shù)通常首字母大寫,用于區(qū)分普通函數(shù)。這種關(guān)系常被稱為原型鏈,它解釋了為何一個對象會擁有定義在其他對象中的屬性和方法。中所有的對象,都有一個屬性,指向?qū)嵗龑ο蟮臉?gòu)造函數(shù)原型由于是個非標準屬性,因此只有和兩個瀏覽器支持,標準方法是。 從這篇文章開始,復(fù)習(xí) MDN 中級教程 的內(nèi)容了,在初級教程中,我和大家分享了一些比較簡單基礎(chǔ)的知識點,并放在我的 【Cute-JavaScript】系...
摘要:本文是重溫基礎(chǔ)系列文章的第十四篇。元,是指程序本身。有理解不到位,還請指點,具體詳細的介紹,可以查看維基百科元編程。攔截,返回一個布爾值。 本文是 重溫基礎(chǔ) 系列文章的第十四篇。 這是第一個基礎(chǔ)系列的最后一篇,后面會開始復(fù)習(xí)一些中級的知識了,歡迎持續(xù)關(guān)注呀! 接下來會統(tǒng)一整理到我的【Cute-JavaScript】的JavaScript基礎(chǔ)系列中。 今日感受:獨樂樂不如眾樂樂...
摘要:系列目錄復(fù)習(xí)資料資料整理個人整理重溫基礎(chǔ)語法和數(shù)據(jù)類型重溫基礎(chǔ)流程控制和錯誤處理重溫基礎(chǔ)循環(huán)和迭代重溫基礎(chǔ)函數(shù)本章節(jié)復(fù)習(xí)的是中的表達式和運算符,用好這些可以大大提高開發(fā)效率。 本文是 重溫基礎(chǔ) 系列文章的第五篇。今日感受:家的意義。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1.語法和數(shù)據(jù)類型 【重溫基礎(chǔ)】2.流程控制和錯誤處理 【重溫基...
摘要:迭代器和生成器將迭代的概念直接帶入核心語言,并提供一種機制來自定義循環(huán)的行為。本文主要會介紹中新增的迭代器和生成器。屬性本身是函數(shù),是當(dāng)前數(shù)據(jù)結(jié)構(gòu)默認的迭代器生成函數(shù)。 本文是 重溫基礎(chǔ) 系列文章的第十三篇。今日感受:每次自我年終總結(jié),都會有各種情緒和收獲。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1.語法和數(shù)據(jù)類型 【重溫基礎(chǔ)】2.流...
閱讀 2806·2021-10-14 09:42
閱讀 3615·2021-10-11 10:59
閱讀 2950·2019-08-30 11:25
閱讀 3083·2019-08-29 16:25
閱讀 3230·2019-08-26 17:40
閱讀 1235·2019-08-26 13:30
閱讀 1151·2019-08-26 11:46
閱讀 1336·2019-08-23 15:22