ES6新增API:Object篇

forceddd發表於2021-11-12

1.Object.is

函式型別:

(v1:any,v2:any)=>boolean;
//接收兩個用於比較是否相等的值,返回一個布林值結果

Object.is(...)函式的比較規則和嚴格相等===基本相同,但是有兩個特殊的值——NaN-0,需要注意:

當進行嚴格相等的比較時,NaN本身是不相等的,+0-0相等的:

NaN===NaN;//false
0===-0;//true

但是在Object.is(...)的判斷規則中,NaN相等的,+0-0不相等(因為+-可以代表方向,-在程式碼中一般是有意義的):

Object.is(NaN,NaN);//true
Object.is(0,-0);//false

也正是因此,當我們需要嚴格地判斷NaN-0時,可以使用Object.is(...),這個函式並不能替代===

2.Object.getOwnPropertySymbols

函式型別:

(obj:any)=>Symbol[];
//接受一個物件,返回這個物件中所有Symbol型別的鍵組成的陣列,不存在Symbol屬性時,返回空陣列

ES6中新增了一個基本型別Symbol,由於Symbol的值獨一無二的特性,使用Symbol作為物件的屬性是很有吸引力的。Object.getOwnPropertySymbols(...)這個方法就是為了取得物件上所有的Symbol屬性。

const obj = {
    [Symbol('prop')]: '我是symbol屬性的值',
    [Symbol.iterator]() {
        return this;
    },
};
console.log(Object.getOwnPropertySymbols(obj)); // [ Symbol(prop), Symbol(Symbol.iterator) ]

3.Object.setPrototypeOf

函式型別:

<T>(obj:T,prototype:Object|null)=>T;
//該函式會將prototype設為obj的原型物件,返回值為obj自身

相較於通過__proto__屬性修改原型物件obj.__proto__ = prototype,使用Object.setPrototypeOf(obj,protorype)是更加合乎規範的,所以當我們有修改原型物件的需求時,最好使用Object.setPrototypeOf(...)

但是需要注意的是,修改一個物件的原型物件的操作是很慢的,這種行為也會使程式碼變得更難懂。我們最好是避免修改物件的原型物件,可以通過Object.create(...)建立帶有我們想要的原型物件的物件。

const obj = {};
const obj2 = {
    name: 'obj2',
};
//儘量避免
Object.setPrototypeOf(obj, obj2);
//稍微推薦
const obj3 = Object.create(obj2);
console.log(obj.name, obj3.name);//obj2 obj2

4.Object.assign

函式型別:

<T,U>(target:T,...objs:U[])=>T&U;
//將所有可列舉屬性的值從一個或多個源物件分配到目標物件,返回目標物件target

Object.assgin(...)的第一個引數是目標物件,其他的引數都是要複製屬性的資料來源物件。該函式會依照資料來源物件傳入的順序,依次將資料來源物件中的可列舉的自身擁有的(非原型鏈上的)屬性,淺複製到目標物件上。

const obj = {
    self: 'self',
};
const obj2 = {
    name: 'obj2',
};
Object.setPrototypeOf(obj, obj2);
Object.defineProperty(obj, 'notEnumerable', {
    enumerable: false,
});
const target = {};
Object.assign(target, null, undefined, obj);
//name屬性是obj的原型物件obj2上的屬性,obj的notEnumerable是不可列舉的,所以最終只複製了一個self屬性
console.log(target);//{ self: 'self' }

需要注意的是,當資料來源物件傳入的是null或者undefined時,該函式不會丟擲錯誤。

相關文章