天天看點

ES6類型擴充-對象擴充

一直以來對象的術語描述沒有統一的标準,于是ES6規範定義了每一個類别的對象,對象的類别如下:

1、普通(Ordinary)對象

具有JS對象所有的預設内部行為

2、特異(Exotic)對象

具有某些與預設行為不符的内部行為

3、标準(Standard)對象

ES6規範中定義的對象,例如,Array、Date等。标準對象既可以是普通對象,也可以是特異對象

4、内建對象

腳本開始執行時存在于JS執行環境中的對象,所有标準對象都是内建對象

當一個對象的屬性與本地變量同名時,隻寫屬性名即可

對象的方法也可以簡寫,消除了冒号和function關鍵字

兩者的唯一差別是,簡寫方法可以使用super關鍵字,普通方法不可以

在ES5中是無法為對象字面量定義可計算屬性名的,比如說屬性名是一個變量。但在ES6中可以通過為屬性名加一對方括号來定義可計算屬性名。

在JS中,判斷兩個值是否相等,通常會使用相等運算符或全等運算符,但是有時候即使使用全等運算符也不一定完全靠得住

ES6引入了<code>Object.is()</code>方法來彌補全等運算符的不準确運算。這個方法接受兩個參數,如果這兩個參數類型相等且具有相同的值,則傳回true,否則傳回false

ES6新增了Object.assign()方法用于對象合并,該方法的第一個參數是目标對象,後面的參數是源對象,源對象的數量不限。

Object.assign()方法可以把源對象按照順序将屬性複制到目标對象中,如果目标對象與源對象有同名屬性,或者源對象與源對象有同名屬性,那麼後面的屬性會覆寫前面的屬性。

注意: 屬性的複制實際上是淺拷貝的過程,并且隻拷貝源對象自身的屬性,對于繼承屬性和不可枚舉屬性是不拷貝的

在ES6中,無論是在嚴格模式還是非嚴格模式下,代碼不再檢查重複屬性,對于每一組重複屬性,都會選取最後一個取值

如果是在ES5嚴格模式下,當同時存在多個同名屬性時會抛出錯誤

ES6嚴格規定了對象的自有屬性被枚舉時的傳回順序,這會影響到Object.getOwnPropertyNames()方法及Reflect.ownKeys傳回屬性的方式,自有屬性枚舉順序的基本規則如下:

1、所有數字鍵按升序排序

2、所有字元串鍵按照它們被加入對象的順序排序

3、所有symbol鍵按照它們被加入對象的順序排序

<code>__proto__</code>屬性,用來讀取或設定目前對象的prototype對象,目前所有浏覽器都部署了該屬性。

标準規定,隻有浏覽器必須部署<code>__proto__</code>屬性。開發過程中最好不要直接使用該屬性,而是使用Object.setPrototypeOf()(寫操作)、Object.getPrototypeOf()(讀操作)、Object.create()(生成操作)來代替

Object.getPrototypeOf(obj)方法用于擷取一個對象的原型對象

Object.setPrototypeOf()方法與proto作用相同,可以改變任意指定對象的原型。該方法接收兩個參數:要改變原型的對象和替代第一個參數原型的對象

對象原型的真實值被儲存在内部專用屬性[[protơtype]]中,調用Object.getPrototypeOf()方法傳回儲存在其中的值,調用Object.setPrototypeOf()方法改變其中的值。然而,這不是操作[[prototype]]值的唯一方法

ES6引入了super引用,使開發者可以更便捷的通路對象原型。

如果想重寫對象執行個體的方法,又需要調用與它同名的原型方法,利用super引用可以這樣寫

super引用相當于指向對象原型的指針,實際上也就是Object.getPrototypeOf(this)的值

如果用es5來寫這個示例,就要複雜一些,而且不容易了解

Super引用在多重繼承情況下非常有用,因為在這種情況下,使用Object.getPrototypeOf()方法将會出現問題

當執行p.sayName()方法時,會調用friend.sayName()方法,而此時的this值為p。Object.getPrototypeOf(this)又會傳回friend對象。是以就會進入遞歸調用直到觸發棧溢出報錯

如果使用super引用就不會有這種問題

super引用不是動态變化的,無論有多少其他方法繼承了sayName()方法,super.sayName()始終指向person.sayName()方法

在ES6以前從未正式定義過"方法"的概念,方法僅僅是一個具有功能而非資料的對象屬性。而在ES6中正式将方法定義為一個函數,它會有一個内部的[[HomeObject]]屬性來容納這個方法從屬的對象

當調用friend.sayName()方法時,該方法内部的[[HomeObject]]屬性值是friend,friend的原型是person,是以super.sayName()等價于person.sayName().call(this)

ES5 引入了<code>Object.keys()</code>方法,傳回一個數組,成員是參數對象自身的(不含繼承的)所有可周遊(enumerable)屬性的鍵名

ES8引入了Object.values和Object.entries,作為周遊一個對象的補充手段,供for...of循環使用

<code>Object.values()</code>方法傳回一個數組,成員是參數對象自身的(不含繼承的)所有可周遊(enumerable)屬性的鍵值

<code>Object.entries()</code>方法傳回一個數組,成員是參數對象自身的(不含繼承的)所有可周遊(enumerable)屬性的鍵值對數組

部落格: https://blog.86886.wang

GitHub: https://github.com/wmui