Object

注:內(nèi)容來(lái)自阮一峰老師的書(shū) ECMAScript 6 入門(mén)

1.屬性的簡(jiǎn)潔表示

const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}

// 等同于
const baz = {foo: foo};

上面代碼表明,ES6 允許在對(duì)象之中,直接寫(xiě)變量。這時(shí),屬性名為變量名, 屬性值為變量的值。
除了屬性簡(jiǎn)寫(xiě),方法也可以簡(jiǎn)寫(xiě)。

const o = {
  method() {
    return "Hello!";
  }
};

// 等同于

const o = {
  method: function() {
    return "Hello!";
  }
};

注意,簡(jiǎn)潔寫(xiě)法的屬性名總是字符串.
如果某個(gè)方法的值是一個(gè) Generator 函數(shù),前面需要加上星號(hào)。

const obj = {
  * m() {
    yield 'hello world';
  }
};

2.屬性名表達(dá)式

JavaScript 定義對(duì)象的屬性,有兩種方法。


image.png

注意,屬性名表達(dá)式與簡(jiǎn)潔表示法,不能同時(shí)使用,會(huì)報(bào)錯(cuò)。屬性名表達(dá)式如果是一個(gè)對(duì)象,默認(rèn)情況下會(huì)自動(dòng)將對(duì)象轉(zhuǎn)為字符串[object Object],這一點(diǎn)要特別小心。


image.png

3.方法的 name 屬性

函數(shù)的name屬性,返回函數(shù)名。對(duì)象方法也是函數(shù),因此也有name屬性。
如果對(duì)象的方法使用了取值函數(shù)(getter)和存值函數(shù)(setter),則name屬性不是在該方法上面,而是該方法的屬性的描述對(duì)象的get和set屬性上面,返回值是方法名前加上get和set。

const obj = {
  get foo() {},
  set foo(x) {}
};

obj.foo.name
// TypeError: Cannot read property 'name' of undefined

const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');

descriptor.get.name // "get foo"
descriptor.set.name // "set foo

有兩種特殊情況:bind方法創(chuàng)造的函數(shù),name屬性返回bound加上原函數(shù)的名字;Function構(gòu)造函數(shù)創(chuàng)造的函數(shù),name屬性返回anonymous。如果對(duì)象的方法是一個(gè) Symbol 值,那么name屬性返回的是這個(gè) Symbol 值的描述。

4.Object.is()

ES5 比較兩個(gè)值是否相等,只有兩個(gè)運(yùn)算符:相等運(yùn)算符(==)和嚴(yán)格相等運(yùn)算符(===)。它們都有缺點(diǎn),前者會(huì)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一種運(yùn)算,在所有環(huán)境中,只要兩個(gè)值是一樣的,它們就應(yīng)該相等。

ES6 提出“Same-value equality”(同值相等)算法,用來(lái)解決這個(gè)問(wèn)題。Object.is就是部署這個(gè)算法的新方法。它用來(lái)比較兩個(gè)值是否嚴(yán)格相等,與嚴(yán)格比較運(yùn)算符(===)的行為基本一致。

Object.is('foo', 'foo')
// true
Object.is({}, {})
// false

不同之處只有兩個(gè):一是+0不等于-0,二是NaN等于自身。

5.Object.assign()

Object.assign方法用于對(duì)象的合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)。
Object.assign方法的第一個(gè)參數(shù)是目標(biāo)對(duì)象,后面的參數(shù)都是源對(duì)象。
注意,如果目標(biāo)對(duì)象與源對(duì)象有同名屬性,或多個(gè)源對(duì)象有同名屬性,則后面的屬性會(huì)覆蓋前面的屬性。
如果只有一個(gè)參數(shù),Object.assign會(huì)直接返回該參數(shù).
如果該參數(shù)不是對(duì)象,則會(huì)先轉(zhuǎn)成對(duì)象,然后返回。由于undefined和null無(wú)法轉(zhuǎn)成對(duì)象,所以如果它們作為參數(shù),就會(huì)報(bào)錯(cuò)。如果非對(duì)象參數(shù)出現(xiàn)在源對(duì)象的位置(即非首參數(shù)),那么處理規(guī)則有所不同。首先,這些參數(shù)都會(huì)轉(zhuǎn)成對(duì)象,如果無(wú)法轉(zhuǎn)成對(duì)象,就會(huì)跳過(guò)。這意味著,如果undefined和null不在首參數(shù),就不會(huì)報(bào)錯(cuò).
其他類型的值(即數(shù)值、字符串和布爾值)不在首參數(shù),也不會(huì)報(bào)錯(cuò)。但是,除了字符串會(huì)以數(shù)組形式,拷貝入目標(biāo)對(duì)象,其他值都不會(huì)產(chǎn)生效果。這是因?yàn)橹挥凶址陌b對(duì)象,會(huì)產(chǎn)生可枚舉屬性。
Object.assign拷貝的屬性是有限制的,只拷貝源對(duì)象的自身屬性(不拷貝繼承屬性),也不拷貝不可枚舉的屬性(enumerable: false),屬性名為 Symbol 值的屬性,也會(huì)被Object.assign拷貝.

注意

  • 1.Object.assign方法實(shí)行的是淺拷貝,而不是深拷貝。
  • 2.對(duì)于這種嵌套的對(duì)象,一旦遇到同名屬性,Object.assign的處理方法是替換,而不是添加。
  • 3.Object.assign可以用來(lái)處理數(shù)組,但是會(huì)把數(shù)組視為對(duì)象。
  • 4.Object.assign只能進(jìn)行值的復(fù)制,如果要復(fù)制的值是一個(gè)取值函數(shù),那么將求值后再?gòu)?fù)制

用途:

  • 1.為對(duì)象添加屬性
  • 2.為對(duì)象添加方法
  • 3.克隆對(duì)象
  • 4.合并多個(gè)對(duì)象
  • 5.為屬性指定默認(rèn)值

6.屬性的可枚舉性和遍歷

ES6 一共有 5 種方法可以遍歷對(duì)象的屬性。
(1)for...in
for...in循環(huán)遍歷對(duì)象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
(2)Object.keys(obj)
Object.keys返回一個(gè)數(shù)組,包括對(duì)象自身的(不含繼承的)所有可枚舉屬性(不含 Symbol 屬性)的鍵名。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一個(gè)數(shù)組,包含對(duì)象自身的所有屬性(不含 Symbol 屬性,但是包括不可枚舉屬性)的鍵名。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一個(gè)數(shù)組,包含對(duì)象自身的所有 Symbol 屬性的鍵名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一個(gè)數(shù)組,包含對(duì)象自身的所有鍵名,不管鍵名是 Symbol 或字符串,也不管是否可枚舉。

7.__proto__Object.setPrototypeOf() / Object.getPrototypeOf()

__proto__屬性(前后各兩個(gè)下劃線),用來(lái)讀取或設(shè)置當(dāng)前對(duì)象的prototype對(duì)象。
Object.setPrototypeOf方法的作用與proto相同,用來(lái)設(shè)置一個(gè)對(duì)象的prototype對(duì)象,返回參數(shù)對(duì)象本身。它是 ES6 正式推薦的設(shè)置原型對(duì)象的方法。/用于讀取一個(gè)對(duì)象的原型對(duì)象。

8.super 關(guān)鍵字

我們知道,this關(guān)鍵字總是指向函數(shù)所在的當(dāng)前對(duì)象,ES6 又新增了另一個(gè)類似的關(guān)鍵字super,指向當(dāng)前對(duì)象的原型對(duì)象。注意,super關(guān)鍵字表示原型對(duì)象時(shí),只能用在對(duì)象的方法之中,用在其他地方都會(huì)報(bào)錯(cuò)。

9.Object.keys(),Object.values(),Object.entries()

ES5 引入了Object.keys方法,返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名。
Object.values方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。
Object.entries方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對(duì)數(shù)組。

10.對(duì)象的擴(kuò)展運(yùn)算符

對(duì)象的解構(gòu)賦值用于從一個(gè)對(duì)象取值,相當(dāng)于將所有可遍歷的、但尚未被讀取的屬性,分配到指定的對(duì)象上面。所有的鍵和它們的值,都會(huì)拷貝到新對(duì)象上面。

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }

由于解構(gòu)賦值要求等號(hào)右邊是一個(gè)對(duì)象,所以如果等號(hào)右邊是undefined或null,就會(huì)報(bào)錯(cuò),因?yàn)樗鼈儫o(wú)法轉(zhuǎn)為對(duì)象。解構(gòu)賦值必須是最后一個(gè)參數(shù),否則會(huì)報(bào)錯(cuò)。
注意,解構(gòu)賦值的拷貝是淺拷貝,即如果一個(gè)鍵的值是復(fù)合類型的值(數(shù)組、對(duì)象、函數(shù))、那么解構(gòu)賦值拷貝的是這個(gè)值的引用,而不是這個(gè)值的副本。
另外,擴(kuò)展運(yùn)算符的解構(gòu)賦值,不能復(fù)制繼承自原型對(duì)象的屬性。

11.Null 傳導(dǎo)運(yùn)算符

編程中,如果讀取對(duì)象內(nèi)部的某個(gè)屬性,往往需要判斷一下該對(duì)象是否存在。比如,要讀取message.body.user.firstName,安全的寫(xiě)法是寫(xiě)成下面這樣。
const firstName = message?.body?.user?.firstName || 'default';
上面代碼有三個(gè)?.運(yùn)算符,只要其中一個(gè)返回null或undefined,就不再往下運(yùn)算,而是返回undefined。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容