Object.is()
ES5比較兩個值是否相等,只有兩個運算符:相等運算符(==)和嚴格相等運算符(===)。它們都有缺點,前者會自動轉換數據類型,后者的NaN不等於自身,以及+0等於-0。用來比較兩個值是否嚴格相等,與嚴格比較運算符(===)的行為基本一致。不同之處只有兩個:一是+0不等於-0,二是NaN等於自身。
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方法的第一個參數是目標對象,后面的參數都是源對象。
var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
注意點
Object.assign方法實行的是淺拷貝,而不是深拷貝。也就是說,如果源對象某個屬性的值是對象,那么目標對象拷貝得到的是這個對象的引用。
常見用途
(1)為對象添加屬性
(2)為對象添加方法
(3)克隆對象
function clone(origin) {
return Object.assign({}, origin);
}
上面代碼將原始對象拷貝到一個空對象,就得到了原始對象的克隆。
不過,采用這種方法克隆,只能克隆原始對象自身的值,不能克隆它繼承的值。如果想要保持繼承鏈,可以采用下面的代碼。
function clone(origin) { let originProto = Object.getPrototypeOf(origin); return Object.assign(Object.create(originProto), origin); }
(4)合並多個對象
(5)為屬性指定默認值
屬性的可枚舉性
對象的每個屬性都有一個描述對象(Descriptor),用來控制該屬性的行為。Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對象。
描述對象的enumerable屬性,稱為”可枚舉性“,如果該屬性為false,就表示某些操作會忽略當前屬性。
ES5有三個操作會忽略enumerable為false的屬性。
for...in循環:只遍歷對象自身的和繼承的可枚舉的屬性Object.keys():返回對象自身的所有可枚舉的屬性的鍵名JSON.stringify():只串行化對象自身的可枚舉的屬性
ES6新增了一個操作Object.assign(),會忽略enumerable為false的屬性,只拷貝對象自身的可枚舉的屬性。
這四個操作之中,只有for...in會返回繼承的屬性。實際上,引入enumerable的最初目的,就是讓某些屬性可以規避掉for...in操作。比如,對象原型的toString方法,以及數組的length屬性,就通過這種手段,不會被for...in遍歷到。
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
屬性的遍歷
ES6一共有5種方法可以遍歷對象的屬性。
(1)for...in
for...in循環遍歷對象自身的和繼承的可枚舉屬性(不含Symbol屬性)。
(2)Object.keys(obj)
Object.keys返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性)。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一個數組,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一個數組,包含對象自身的所有Symbol屬性。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一個數組,包含對象自身的所有屬性,不管是屬性名是Symbol或字符串,也不管是否可枚舉。
以上的5種方法遍歷對象的屬性,都遵守同樣的屬性遍歷的次序規則。
- 首先遍歷所有屬性名為數值的屬性,按照數字排序。
- 其次遍歷所有屬性名為字符串的屬性,按照生成時間排序。
- 最后遍歷所有屬性名為Symbol值的屬性,按照生成時間排序。
