變數功能被加強了、函式功能被加強了,那麼作為JavaScript中最普遍的物件,不加強對得起觀眾嗎?
物件類別
在ES6中,物件分為下面幾種叫法。(不需要知道概念)
1、普通物件
2、特異物件
3、標準物件
4、內建物件
物件字面量語法擴充
隨便開啟一個js檔案,物件都無處不在,看一個簡單的物件。
{
a: 2
}
ES6針對物件的語法擴充套件了一下功能
1、屬性初始值簡寫
//ES5
function a(id) {
return {
id: id
};
};
//ES6
const a = (id) => ({
id
})
2、物件方法簡寫
// ES5
const obj = {
id: 1,
printId: function() {
console.log(this.id)
}
}
// ES6
const obj = {
id: 1,
printId() {
console.log(this.id)
}
}
3、屬性名可計算
屬性名可以傳入變數或者常量,而不只是一個固定的字串。
const id = 5
const obj = {
[`my-${id}`]: id
}
console.log(obj[`my-5`]) // 5
ES6物件新增方法
在Object原始物件上新增方法,原則上來說不可取,但是為了解決全世界各地提交的issue,在ES6中的全域性Object物件上新增了一些方法。
1、Object.is()
用來解決JavaScript中特殊型別 == 或者 === 異常的情況。
下面是一些異常情況
//實際出現了異常(錯誤輸出)
console.log(NaN === NaN) // false
console.log(+0 === -0) // true
console.log(5 == "5") //true
//我們期望的目標輸出(正確輸出)
console.log(NaN === NaN) // true
console.log(+0 === -0) // false
console.log(5 == "5") //false
為了解決歷遺留問題,新增了Object.is()來處理2個值的比較。
console.log(Object.is(NaN, NaN)) // true
console.log(Object.is(+0, -0)) // false
console.log(Object.is(5, "5")) //false
2、Object.assign()
也許你已經見過或者使用過這個方法了,那這個新增的方法解決了什麼問題呢?
答:混合(Mixin)。
mixin是一個方法,實現了拷貝一個物件給另外一個物件,返回一個新的物件。
下面是一個mixin方法的實現,這個方法實現的是淺拷貝。將b物件的屬性拷貝到了a物件,合併成一個新的物件。
//mixin不只有這一種實現方法。
function mixin(receiver, supplier) {
Object.keys(supplier).forEach((key) => {
receiver[key] = supplier[key]
})
return receiver
}
let a = {name: `sb`};
let b = {
c: {
d: 5
}
}
console.log(mixin(a, b)) // {"name":"sb","c":{"d":5}}
寫這樣一個mixin方法是不是很煩,而且每個專案都得引入這個方法,現在,ES6給我們提供了一個現成的方法Object.assign()來做mixin的事情。
假設要實現上面的mixin方法,你只需要給Object.assign()傳入引數即可。
console.log(Object.assign(a, b))// {"name":"sb","c":{"d":5}}
使用Object.assign(),你就可以不是有繼承就能獲得另一個物件的所有屬性,快捷好用。
看一個實現Component的例子。
//宣告一個建構函式Component
class Component {}
//給建構函式設定原型方法
Component.prototype = {
componentWillMount() {},
componentDidMount() {},
render() {console.log(`render`)}
}
//定義一個新的物件
let MyComponent = {}
//新物件繼承了Component的所有方法和屬性。
Object.assign(MyComponent, Component.prototype)
console.log(MyComponent.render()) // render
在react的reducer中,每次傳入新的引數返回新的state,你都可能用到Object.assign()方法。
重複的物件字面量屬性
ES5的嚴格模式下,如果你的物件中出現了key相同的情況,那麼就會丟擲錯誤。而在ES6的嚴格模式下,不會報錯,後面的key會覆蓋掉前面相同的key。
const state = {
id: 1,
id: 2
}
console.log(state.id) // 2
自有屬性列舉順序
這個概念看起來比較模糊,如果你看了下面的例子,你可能就會明白在說什麼了。
const state = {
id: 1,
5: 5,
name: "eryue",
3: 3
}
Object.getOwnPropertyNames(state)
//["3","5","id","name"] 列舉key
Object.assign(state, null)
//{"3":3,"5":5,"id":1,"name":"eryue"}
上面的例子的輸出結果都有個規律,就是數字提前,按順序排序,接著是字母排序。而這種行為也是ES6新增的標準。你還可以自己測試一下其他方法是不是也支援列舉自動排序。比如Object.keys(), for in 等。
增強物件原型
如果你想定義一個物件,你會想到很多方法。
let a = {}
let b = Object.create(a)
function C() {}
class D {}
那麼,ES6是如何在這麼強大的物件上面繼續增強功能呢?
1、允許改變物件原型
改變物件原型,是指在物件例項化之後,可以改變物件原型。我們使用 Object.setPrototypeOf() 來改變例項化後的物件原型。
let a = {
name() {
return `eryue`
}
}
let b = Object.create(a)
console.log(b.name()) // eryue
//使用setPrototypeOf改變b的原型
let c = {
name() {
return "sb"
}
}
Object.setPrototypeOf(b, c)
console.log(b.name()) //sb
2、簡化原型訪問的super引用
這一個知識你可以看書籍原文,我目前想不到實際業務程式碼來分析。
方法的定義
ES6明確了方法的定義。
let a = {
//方法
name() {
return `eryue`
}
}
//函式
function name() {}
估計習慣了函式和方法切換的我們,還是不用太在意這些具體的叫法。
總結
本章講解了物件字面量語法擴充,ES6新增方法,允許重複的物件字面量屬性,自有列舉屬性排序,增強物件原型,明確了方法的定義。
我們平時開發中比較常用的是前面4種新增的功能,尤其是Object.assign()的使用。但是,就算把全部新增的功能記住也不是難事。所以,全都記住吧!