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
函数类型:
(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
函数类型:
(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
时,该函数不会抛出错误。