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
時,該函式不會丟擲錯誤。