Object.is()
ES5 比较两个值是否相等,只有两个运算符:相等运算符(==
)和严格相等运算符(===
)。它们都有缺点,前者会自动转换数据类型,后者的NaN
不等于自身,以及+0
等于-0
。
ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is
就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0
不等于-0
,二是NaN
等于自身。
Object.is(NaN, NaN) // trueObject.is(+0, -0) // false
ES5 可以通过下面的代码,部署Object.is
。
Object.defineProperty(Object, 'is', { value: function(x, y) { if (x === y) { // 针对+0 不等于 -0的情况 return x !== 0 || 1 / x === 1 / y; } // 针对NaN的情况 return x !== x && y !== y; }, configurable: true, enumerable: false, writable: true});
Object.assign()
Object.assign
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
Object.assign(target, source1, source2, ...);
Object.assign
方法的第一个参数是目标对象,后面的参数都是源对象。
如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。
非对象类型的值,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
{ "0": "h", "1": "i", "2": "!" }
Object.assign({b: 'c'}, Object.defineProperty({}, 'invisible', { enumerable: false, value: 'hello' }))
Object.defineProperty用于定义对象属性具体情况get set value enumerable等属性描述符。
(1)浅拷贝
Object.assign
方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
(2)同名属性的替换
对于这种嵌套的对象,一旦遇到同名属性,Object.assign
的处理方法是替换,而不是添加。
(3)数组的处理
Object.assign
可以用来处理数组,但是会把数组视为对象。
Object.assign
把数组视为属性名为 0、1、2 的对象,后边加上的数组会进行覆盖。
(4)取值函数的处理
Object.assign
只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
一些函数库提供Object.assign
的定制版本(比如 Lodash 的_.defaultsDeep
方法),可以得到深拷贝的合并。