1. Object.is()
在ES6之前我們總是通過(guò)相等運(yùn)算符==
或者嚴(yán)格相等運(yùn)算符===
去判斷兩個(gè)值是否相等,但是這兩者都有一定的缺陷姻僧。所以JavaScript
缺乏一種運(yùn)算,能夠在所有環(huán)境中判斷兩個(gè)值是不是一樣的谒养,如果是一樣的就應(yīng)該相等滔岳。
ES6提出了同值相等算法,用來(lái)解決這個(gè)問(wèn)題乏奥,該算法與===
表現(xiàn)較為類似,不同之處在于比較+0
與-0
和比較NaN
與其自身:
+0 === -0 // true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
在沒(méi)有部署Object.is()
方法的環(huán)境可以通過(guò)以下代碼來(lái)部署該方法:
Object.defineProperty(Object, 'is', {
value: function(x, y) {
if (x === y) {
// 針對(duì)+0 不等于 -0的情況
return x !== 0 || 1 / x === 1 / y;
}
// 針對(duì)NaN的情況
return x !== x && y !== y;
},
configurable: true,
enumerable: false,
writable: true
})
2. Object.assign()
Object.assign()
主要用于對(duì)象的合并翔忽,其行為是將源對(duì)象的所有可枚舉屬性和方法添加到目標(biāo)對(duì)象中英融。
const [target, source] = [{}, {name: 'bing', age: 23}]
Object.assign(target, source)
target // {name: 'bing', age: 23}
其行為與擴(kuò)展運(yùn)算符類似盏檐,不過(guò)擴(kuò)展運(yùn)算符是把所有的源對(duì)象的屬性和方法都放到了一個(gè)新的對(duì)象中歇式,但是Object.assign()
是把源對(duì)象的屬性和方法放到了目標(biāo)對(duì)象中。
2.1 如果有同名屬性
如果有同名屬性胡野,那么后面的屬性會(huì)覆蓋前面的屬性值
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ù)不是對(duì)象
嚴(yán)謹(jǐn)?shù)膩?lái)說(shuō)材失,如果源對(duì)象參數(shù)不是對(duì)象,或者是特殊對(duì)象(正則表達(dá)式硫豆,Date對(duì)象等)龙巨,那么該方法會(huì)直接跳過(guò)參數(shù)而不會(huì)報(bào)錯(cuò)
let a = new Date()
let b = {}
Object.assign(b, a) // {}
如果目標(biāo)對(duì)象不是對(duì)象或者是特殊對(duì)象,那么會(huì)返回一個(gè)包裝對(duì)象熊响,當(dāng)然undefined
和null
除外
Object.assign(null) // Cannot convert undefined or null to object
Object.assign(undefined) // Cannot convert undefined or null to object
// 下面的都會(huì)返回一個(gè)包裝對(duì)象
Object.assign(NaN)
Object.assign(2)
Object.assign('string')
2.3 參數(shù)是數(shù)組的情況
因?yàn)閿?shù)組也是一種對(duì)象旨别,當(dāng)使用該方法時(shí),數(shù)組會(huì)被當(dāng)做對(duì)象處理:
Object.assign([1, 2, 3, 6], [3, 4, 5]) // [3, 4, 5, 6]
上述代碼中因?yàn)槟繕?biāo)數(shù)組中索引從0-3的位置都被原數(shù)組給覆蓋了汗茄,所以返回的數(shù)組是[3, 4, 5, 6]
2.4 對(duì)取值函數(shù)的處理
Object.assign
只能進(jìn)行值的復(fù)制秸弛,如果要復(fù)制的值是一個(gè)取值函數(shù),那么將求值后再?gòu)?fù)制。
const source = {
get foo() { return 1 }
};
const target = {};
Object.assign(target, source)
// { foo: 1 }
上面代碼中递览,source
對(duì)象的foo
屬性是一個(gè)取值函數(shù)叼屠,Object.assign
不會(huì)復(fù)制這個(gè)取值函數(shù),只會(huì)拿到值以后绞铃,將這個(gè)值復(fù)制過(guò)去镜雨。
3. Object.getOwnPropertyDescriptors()
ES5 的Object.getOwnPropertyDescriptor()
方法會(huì)返回某個(gè)對(duì)象屬性的描述對(duì)象(descriptor)
。ES2017 引入了Object.getOwnPropertyDescriptors()
方法儿捧,返回指定對(duì)象所有自身屬性(非繼承屬性)的描述對(duì)象荚坞。
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 } }
上述代碼中,使用該方法后反悔了一個(gè)對(duì)象纯命,對(duì)象中包括了源對(duì)象的所有自身的屬性的屬性描述對(duì)象西剥,該方法的出現(xiàn)主要是為了解決Object.assign
無(wú)法拷貝get
和set
,使用Object.getOwnPropertyDescriptors()
方法配合Object.defineProperties()
方法亿汞,就可以實(shí)現(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è)置原型對(duì)象,在某些時(shí)候我們想新生成一個(gè)對(duì)象使之繼承現(xiàn)有對(duì)象的原型疗我,我們可以采用以下方法:
// 方法一
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
方法返回一個(gè)數(shù)組咆畏,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷enumerable
屬性的鍵值。
const a = {name: 'bing'}
a.__proto__.age = 23 // 繼承屬性
Object.defineProperty(a, 'gender', {value: 'male', enumerable: false})
// 不可枚舉屬性
Object.values(a) // ["bing"] 只返回自身的可枚舉屬性
如果該方法的參數(shù)是一個(gè)字符串吴裤,那么將會(huì)得到令人驚喜的結(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"]
上述三種方法都能把一個(gè)字符串分解為包含字符的數(shù)組
6. Object.entries()
Object.entries()
方法返回一個(gè)數(shù)組旧找,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對(duì)數(shù)組。
Object.entries
的基本用途是遍歷對(duì)象的屬性麦牺。
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方法的另一個(gè)用處是钮蛛,將對(duì)象轉(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()
的逆操作剖膳,用于將一個(gè)鍵值對(duì)數(shù)組轉(zhuǎn)為對(duì)象魏颓。
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }
該方法的主要目的,是將鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu)還原為對(duì)象吱晒,因此特別適合將 Map
結(jié)構(gòu)轉(zhuǎn)為對(duì)象甸饱。