1. Object.is()
在ES6之前我們總是通過相等運算符==或者嚴(yán)格相等運算符===去判斷兩個值是否相等,但是這兩者都有一定的缺陷。所以JavaScript缺乏一種運算,能夠在所有環(huán)境中判斷兩個值是不是一樣的,如果是一樣的就應(yīng)該相等。
ES6提出了同值相等算法,用來解決這個問題,該算法與===表現(xiàn)較為類似,不同之處在于比較+0與-0和比較NaN與其自身:
+0 === -0 // true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
在沒有部署Object.is()方法的環(huán)境可以通過以下代碼來部署該方法:
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
})
2. Object.assign()
Object.assign()主要用于對象的合并,其行為是將源對象的所有可枚舉屬性和方法添加到目標(biāo)對象中。
const [target, source] = [{}, {name: 'bing', age: 23}]
Object.assign(target, source)
target // {name: 'bing', age: 23}
其行為與擴(kuò)展運算符類似,不過擴(kuò)展運算符是把所有的源對象的屬性和方法都放到了一個新的對象中,但是Object.assign()是把源對象的屬性和方法放到了目標(biāo)對象中。
2.1 如果有同名屬性
如果有同名屬性,那么后面的屬性會覆蓋前面的屬性值
let a = {name: 'bing'}
let b = {name: 'yan', age: 24}
let c = {name: 'can', age: 27}
Object.assign(a,b,c) // {name: "can", age: 27}
2.2 如果參數(shù)不是對象
嚴(yán)謹(jǐn)?shù)膩碚f,如果源對象參數(shù)不是對象,或者是特殊對象(正則表達(dá)式,Date對象等),那么該方法會直接跳過參數(shù)而不會報錯
let a = new Date()
let b = {}
Object.assign(b, a) // {}
如果目標(biāo)對象不是對象或者是特殊對象,那么會返回一個包裝對象,當(dāng)然undefined和null除外
Object.assign(null) // Cannot convert undefined or null to object
Object.assign(undefined) // Cannot convert undefined or null to object
// 下面的都會返回一個包裝對象
Object.assign(NaN)
Object.assign(2)
Object.assign('string')
2.3 參數(shù)是數(shù)組的情況
因為數(shù)組也是一種對象,當(dāng)使用該方法時,數(shù)組會被當(dāng)做對象處理:
Object.assign([1, 2, 3, 6], [3, 4, 5]) // [3, 4, 5, 6]
上述代碼中因為目標(biāo)數(shù)組中索引從0-3的位置都被原數(shù)組給覆蓋了,所以返回的數(shù)組是[3, 4, 5, 6]
2.4 對取值函數(shù)的處理
Object.assign只能進(jìn)行值的復(fù)制,如果要復(fù)制的值是一個取值函數(shù),那么將求值后再復(fù)制。
const source = {
get foo() { return 1 }
};
const target = {};
Object.assign(target, source)
// { foo: 1 }
上面代碼中,source對象的foo屬性是一個取值函數(shù),Object.assign不會復(fù)制這個取值函數(shù),只會拿到值以后,將這個值復(fù)制過去。
3. Object.getOwnPropertyDescriptors()
ES5 的Object.getOwnPropertyDescriptor()方法會返回某個對象屬性的描述對象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()方法,返回指定對象所有自身屬性(非繼承屬性)的描述對象。
onst 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 } }
上述代碼中,使用該方法后反悔了一個對象,對象中包括了源對象的所有自身的屬性的屬性描述對象,該方法的出現(xiàn)主要是為了解決Object.assign無法拷貝get和set,使用Object.getOwnPropertyDescriptors()方法配合Object.defineProperties()方法,就可以實現(xiàn)正確拷貝。
onst source = {
set foo(value) {
console.log(value);
}
};
const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target2, 'foo')
// { get: undefined,
// set: [Function: set foo],
// enumerable: true,
// configurable: true }
4. Object.setPrototypeOf()
ES6 推薦使用該方法設(shè)置原型對象,在某些時候我們想新生成一個對象使之繼承現(xiàn)有對象的原型,我們可以采用以下方法:
// 方法一
const a = {name: 'bing'}
const b = a.constructor() // b繼承了a的原型
// 方法二
const a = {name: 'bing'}
const b = {}
Object.setPrototypeOf(b, Object.getPrototypeOf(a))
5. Object.values()
Object.values方法返回一個數(shù)組,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷enumerable屬性的鍵值。
const a = {name: 'bing'}
a.__proto__.age = 23 // 繼承屬性
Object.defineProperty(a, 'gender', {value: 'male', enumerable: false})
// 不可枚舉屬性
Object.values(a) // ["bing"] 只返回自身的可枚舉屬性
如果該方法的參數(shù)是一個字符串,那么將會得到令人驚喜的結(jié)果:
Object.values('string') // ["s", "t", "r", "i", "n", "g"]
[...'string'] // ["s", "t", "r", "i", "n", "g"]
Array.from('string') // ["s", "t", "r", "i", "n", "g"]
上述三種方法都能把一個字符串分解為包含字符的數(shù)組
6. Object.entries()
Object.entries()方法返回一個數(shù)組,成員是參數(shù)對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對數(shù)組。
Object.entries的基本用途是遍歷對象的屬性。
let obj = { one: 1, two: 2 };
for (let [k, v] of Object.entries(obj)) {
console.log(
`${JSON.stringify(k)}: ${JSON.stringify(v)}`
);
}
// "one": 1
// "two": 2
Object.entries方法的另一個用處是,將對象轉(zhuǎn)為真正的Map結(jié)構(gòu)。
const obj = { foo: 'bar', baz: 42 };
const map = new Map(Object.entries(obj));
map // Map { foo: "bar", baz: 42 }
Object.fromEntries()方法是Object.entries()的逆操作,用于將一個鍵值對數(shù)組轉(zhuǎn)為對象。
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }
該方法的主要目的,是將鍵值對的數(shù)據(jù)結(jié)構(gòu)還原為對象,因此特別適合將 Map 結(jié)構(gòu)轉(zhuǎn)為對象。