对象的新增方法
1.Object.is()
用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
Object.is('foo', 'foo') // true Object.is({}, {}) // false
不同之处只有两个:一是+0
不等于-0
,二是NaN
等于自身。
+0 === -0 //true NaN === NaN // false Object.is(+0, -0) // false Object.is(NaN, NaN) // true
2.Object.assign()
用于对象的合并,将源对象的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 }; const source1 = { b: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const source1 = { b: 2, c: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性。属性名为Symbol值的属性,也会被Object.assign拷贝。
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用
(3)数组的处理
Object.assign可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3]
上面代码中,Object.assign把数组视为属性名为0、1、2的对象,因此原数组的0号属性4覆盖了目标数组的0号属性1.
(4)取值函数的处理
Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
const source = { get foo() { return 1 } }; const target = {}; Object.assign(target, source) // { foo: 1 }
上面代码中,source对象的foo属性是一个取值函数,Object.assign不会复制这个取值函数,只会拿到值以后,将这个值复制过去。
3.Object.getOwnPropertyDescriptors()
返回指定对象所有自身属性(非继承属性)的描述对象。
也就是返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象。
const obj = { foo: 123, get bar() { return 'abc' } }; Object.getOwnPropertyDescriptors(obj) // { foo: // { value: 123, // writable: true, // enumerable: true, // configurable: true }, // bar: // { get: [Function: get bar], // set: undefined, // enumerable: true, // configurable: true } }
注意:Object.assign方法总是拷贝一个属性的值,而不会拷贝它背后的赋值方法或取值方法。
该方法可以解决Object.assign()无法正确拷贝get属性和set属性的问题。
要配合Object.defineProperties()方法,就可以是实现正确拷贝了。
4._proto_属性,
用来读取或设置当前对象的prototype对象。(不推荐使用)
Object.setPrototypeOf()
(写操作)、Object.getPrototypeOf()
(读操作)、Object.create()
(生成操作)代替。
_proto_调用的是Object.prototype._proto_
5.Object.setPrototypeOf()
该方法的作用与_proto_相同,用来设置一个对象的prototype对象,返回参数对象本身。
// 格式 Object.setPrototypeOf(object, prototype)
该方法等同于下面的函数:
function setPrototypeOf(obj, proto) { obj.__proto__ = proto; return obj; }
例子:
let proto = {}; let obj = { x: 10 }; Object.setPrototypeOf(obj, proto); proto.y = 20; proto.z = 40; obj.x // 10 obj.y // 20 obj.z // 40
将proto对象设为obj对象的原型,所以从obj对象可以读取proto对象的属性。
//如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。
所以如果第一个参数是undefined或null,就会报错。
5.Object.getPrototypeOf()
该方法与Object.setPrototype方法配套,用于读取一个对象的原型对象。
Object.getPrototypeOf(obj);
6.Object.keys()
返回一个数组,成员是参数对象自身的(不含继承)所有可遍历属性的键名
var obj = { foo: 'bar', baz: 42 }; Object.keys(obj) // ["foo", "baz"]
7.Object.values()
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值。
const obj = { foo: 'bar', baz: 42 }; Object.values(obj) // ["bar", 42]
数组的结果从小到大排序。
Object.values(obj)会过滤属性名为Symbol值的属性
Object.create
方法的第二个参数添加的对象属性,如果不显式声明,默认是不可遍历的,属性描述对象的enumerable
默认是false.
8.Object.create()
来创建一个新对象,使用现有的对象来提供新创建对象的_proto_.
语法:Object.create(proto[, propertiesObject])
proto:新创建对象的原型对象propertiesObject:是对象的属性描述符,可选。
返回值:
一个新对象,带着指定的原型对象和属性
8.Object.enteries()
返回一个数组,成员是参数对象自身的(不含继承)所有可遍历属性的键值对数组。
const obj = { foo: 'bar', baz: 42 }; Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
除了返回值不一样,该方法的行为与Object.values基本一致。
如果原对象的属性名是一个Symbol值,该属性会被忽略。
Object.entries的基本用途是遍历对象的属性。
9.Object.fromEntries()
Object.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。
Object.fromEntries([ ['foo', 'bar'], ['baz', 42] ]) // { foo: "bar", baz: 42 }