總結(jié)Es6對象擴(kuò)展了哪些功能

前言

JavaScript中耿币,幾乎每一個(gè)值都是某種特定的類型對象制圈,Es6也著重提升了對象的功能性睹酌,Es6通過多種方式來加強(qiáng)對象的使用邓尤,通過簡單的語法擴(kuò)展佑菩,提供更多操作對象及與對象交互的方法。下面來介紹它們裁赠。

對象字面量語法擴(kuò)展

對象字面量如此就行殿漠,就是我們想創(chuàng)建對象,不在需要編寫冗余的代碼佩捞。直接通過的它的簡潔語法就可以實(shí)現(xiàn)绞幌。那么看看Es6為對象做了那些特性吧。

屬性初始值的簡寫

在Es5中一忱,對象字面量只是簡單的鍵值和集合莲蜘,這意味著初始化屬性有一些重復(fù)。

function person(name) {
    return {
        name: name
    }
}

在Es6中帘营,通過屬性的簡寫則可以省去這name屬性一遍票渠,當(dāng)一個(gè)對象的屬性和變量同名時(shí),則可以省去冒號和值芬迄∥是辏看如下案例

function person(name) {
    return {
        name
    }
}

對象方法的簡寫語法

Es6也改進(jìn)了對象字面量的對象簡寫方法,在Es5中禀梳,定義對象方法必須的得寫完整名稱才可以杜窄。

Es5案例

let person = {
    test: function() {}
}

Es6案例

let person() {
    test() {}
}

通過Es6對象的方法簡寫,定義的是一個(gè)匿名表達(dá)式算途,這個(gè)函數(shù)擁有和Es5一模一樣的特性塞耕。Es5定義對象函數(shù)和Es6簡寫定義的函數(shù)唯一區(qū)別,簡寫的函數(shù)可以使用super嘴瓤。

可計(jì)算屬性名

在Es5中扫外,如果想要通過計(jì)算得到屬性名莉钙,則需要用[]方括號代替。

let person = {}
let value = "hello WaRen"
person["wa ren"] = "蛙人"
person[value] = "value"

上面example中筛谚,是我們在es5中的做法胆胰,如果對象的key值是一個(gè)變量,那我們就使用對象方括號添加刻获。

在Es6中,可在對象字面量中使用可計(jì)算屬性名稱瞎嬉,我們來看下面例子

let key = "name"
let person = {
    [key]: "蛙人" // 在對象字面量中這樣使用[]方括號定義key是Es6語法
    [`${key}_test`]: "test"
}

上面這種在對象字面量中使用方括號表示該屬性名是可以計(jì)算的蝎毡,可以寫表達(dá)式的,然后最終key值都會以字符串類型返回氧枣。切記沐兵,在對象字面量中使用方括號[]定義key值是Es6中的語法。本人也是剛知道(基礎(chǔ)不扎實(shí) 嗚嗚嗚)便监,經(jīng)測試bable轉(zhuǎn)換Es6轉(zhuǎn)Es5可以看到結(jié)果扎谎。

重復(fù)的對象字面量屬性

在Es5嚴(yán)格模式下加入了對象字面量重復(fù)屬性的驗(yàn)證,當(dāng)同時(shí)存在多個(gè)同名屬性時(shí)會拋出異常烧董』侔校看下面例子

"use strict"
var person = {
    name: "蛙人",
    name: "張三" // 在Es5嚴(yán)格模式下會拋出語法錯(cuò)誤
}

在Es5嚴(yán)格模式下時(shí),第二個(gè)屬性name會觸發(fā)一個(gè)語法錯(cuò)誤逊移,但是在Es6中重復(fù)屬性檢查被移除了预吆,Es6中無論是在嚴(yán)格模式下,還是不在嚴(yán)格模式下代碼都不會進(jìn)行重復(fù)屬性驗(yàn)證胳泉,對于重復(fù)屬性都是后面的覆蓋前面的拐叉。ps: 這個(gè)我也是剛剛知道 流下了沒技術(shù)的眼淚 。扇商。凤瘦。

"use strict"
let person = {
    name: "蛙人",
    name: "張三"
}

在上面example中,我們可以看到案铺,這是Es6標(biāo)準(zhǔn)重復(fù)屬性并沒有拋出異常而是后面對象覆蓋前面對象蔬芥,最后name屬性為"張三",我們現(xiàn)在瀏覽器運(yùn)行的都是Es6標(biāo)準(zhǔn)控汉。

Es6對象新增的方法

Es6中在全局Object對象上引入了一些新方法坝茎。

Object.is

我們在Es5中的時(shí)候經(jīng)常使用== 相等運(yùn)算符 or === 全等運(yùn)算符來比較值,然而在Es5中相等運(yùn)算符或者全等運(yùn)算符也不完全準(zhǔn)確暇番,這里拿官網(wǎng)說的舉個(gè)例子嗤放,+0和-0這個(gè)在JavaScript引擎中被表示兩個(gè)不同的實(shí)體,而使用全等運(yùn)算符或者相等運(yùn)算符都會返回ture, 同樣NaN == NaN返回false壁酬。然而Es6中出現(xiàn)了Object.is方法來彌補(bǔ)這些不足次酌,Object.is方法接收2個(gè)參數(shù)恨课,如果這兩個(gè)參數(shù)值相等并且類型也相等,則返回true

console.log(+0 == -0) // ture
console.log(+0 === -0) // true
console.log(Object.is(+0, -0)) // false

console.log(NaN == NaN) // false
console.log(NaN === NaN) // false
console.log(Object.is(NaN, NaN)) // true

console.log(10 == "10") // true
console.log(10 === "10") // false
console.log(Object.is(10, "10")) // false

上面example中岳服,我們可以看到Object.is方法是挺嚴(yán)格的剂公,但是這個(gè)只是處理特殊情況下使用,所以我們沒必要拋棄== or ===吊宋。

Object.assign

Object.assign方法可以接收任意數(shù)量源對象纲辽,第一個(gè)參數(shù)是接收者,也就是最終的返回值璃搜,第二個(gè)參數(shù)以后都是會復(fù)制到第一個(gè)參數(shù)里面拖吼,所以如果有多個(gè)源對象具有同名屬性key值,那么則靠后的對象會覆蓋靠前的對象这吻。來看下面例子

let test1 = {
    name: "蛙人"
}
let test2 = {
    name: "張三"
}
let result = Object.assign({}, test1, test2)
console.log(result)  // {name: "張三"}

上面example中吊档,可以看到上面的對象屬性如果具有同名的,后面的則會覆蓋前面的唾糯。如果參數(shù)里傳入的是非對象也能執(zhí)行怠硼,只不過會忽略。來看下面例子

let result = Object.assign({}, 1, 2, 3)
console.log(result)  // {}

注意: Object.assign方法不能將取值函數(shù)(訪問器屬性)復(fù)制到對象中移怯,由于Object.assign方法執(zhí)行了賦值操作香璃,那么對象最終會轉(zhuǎn)換成一個(gè)普通的屬性。

let test = {
    get name() {
      return "蛙人"
    }
}
let result = Object.assign({}, test)
console.log(Object.getOwnPropertyDescriptor(result, "name")) // {configurable: true enumerable: true value: "蛙人" writable: true}

上面example中舟误,可以看到我們復(fù)制對象的最終結(jié)果增显,取值函數(shù)確實(shí)丟失了,我們可以根據(jù)獲取對象的描述屬性可以看到脐帝。如果不懂對象的描述屬性可以看我這篇文章《深入理解JavaScript對象》

Object.setPrototypeOf

在Es5中同云,提供了Object.getPrototypeOf方法獲取對象的原型,然而Es5中并沒有提供設(shè)置對象的原型的方法堵腹,如果我們想要設(shè)置對象的原型炸站,xx.__proto__ = xx.__proto__ 顯然這樣寫也是沒問題的,但是并不合理疚顷。所以Es6提供了Object.setPrototypeOf方法, 這個(gè)方法接收兩個(gè)參數(shù)旱易,第一個(gè)就是被修改的對象,第二個(gè)是原型對象腿堤。來看下面例子

let person = {}
function Fn() {}
let fn = new Fn()
Object.setPrototypeOf(person, fn)
console.log(person)

上面example中阀坏,可以看到就是把person的原型對象修改成fn的原型對象,這時(shí)你在訪問person對象就可以清楚的看到原型對象已經(jīng)被更改了笆檀。

Object.values

Object.values方法返回一個(gè)數(shù)組忌堂,成員是參數(shù)對象自身的,不包含繼承和原型上的

let person = {
    name: "蛙人",
    age: 24,
    sex: "male"
}
console.log(Object.values(person)) // ["蛙人", 24, "male"]

Object.entries

Object.entries方法返回一個(gè)數(shù)組(也就是一個(gè)二維數(shù)組)酗洒,成員是參數(shù)對象自身的士修,屬性的鍵值對數(shù)組枷遂,不包含繼承和原型上的。

let person = {
    name: "蛙人",
    age: 24,
    sex: "male"
}
console.log(Object.entries(person)) // [["name", "蛙人"], ["age", 24], ["sex", "male"]]

Object.fromEntries

Object.fromEntriesObject.entries的反向操作棋嘲,返回值是一個(gè)對象酒唉,用于將一個(gè)鍵值對數(shù)組轉(zhuǎn)為對象。

let testArr = [
    ["name", "蛙人"],
    ["age", 24],
    ["sex", "male"]
]
console.log(Object.fromEntries(testArr)) // {name: "蛙人", age: 24, sex: "male"}

自有對象屬性枚舉順序

在Es5中沒有定義對象屬性的枚舉順序沸移,是由js引擎廠商自行決定的痪伦。然而,在Es6中規(guī)定了對象自有屬性被枚舉返回的順序雹锣。自有屬性枚舉順序的基本規(guī)則如下:

  • 所有數(shù)字鍵按升序排序
  • 所有字符串鍵按加入對象的順序排序
  • 所有symbol鍵按加入對象的順序排序
let o = {
    4: 4,
    1: 1,
    b: "b",
    a: "a"
}
o.c = "c"

console.log(Object.keys(o)) // ["1", "4", "b", "a", "c"]
console.log(Object.getOwnPropertyNames(o)) // ["1", "4", "b", "a", "c"]
for (let i in o) {
    console.log(i) // 1 4 b a c
}

上面example中网沾,可以看到對象枚舉屬性都是根據(jù)Es6中規(guī)則順序來返回的,請注意 ,對于數(shù)字鍵笆制,盡管在對象字面量中順序是隨意的,但是在枚舉時(shí)會被重新組合和排序涣达。字符串緊跟數(shù)字鍵后面在辆,并按照該屬性在對象里的順序返回,最后是動態(tài)添加字符串健值度苔。

簡化原型訪問的Super引用

在Es6中匆篓,新提供了super關(guān)鍵字,該方法是為了簡化獲取當(dāng)前的原型的對象使用的寇窑。來看下面例子

Es5案例

let person = {
    getName() {
      return Object.getPrototypeOf(this).getVal.call(this)
    }
}
let o = {
    getVal() {
      return "蛙人"
    }
}

Object.setPrototypeOf(person, o)
console.log(person.getName()) // 蛙人

上面example中鸦概,可以看到先把person的原型設(shè)置為o對象,然后調(diào)用person對象時(shí)甩骏,該getName方法里又獲取了當(dāng)前的原型窗市,調(diào)用原型上的方法,也就是調(diào)用的o對象的方法饮笛。

Es6案例

let person = {
    getName() {
      return super.getVal.call(this)
    }
}
let o = {
    getVal() {
      return "蛙人"
    }
}

Object.setPrototypeOf(person, o)
console.log(person.getName()) // 蛙人

上面example中咨察,可以看到我們把上面代碼稍微調(diào)整了一下,把Object.getPrototypeOf換成了super關(guān)鍵字福青。super關(guān)鍵字作用就是可以代替Object.getPrototypeOf方法訪問對象原型摄狱。但是super關(guān)鍵字也是有個(gè)弊端就是只能在對象字面量的方法簡寫情況下使用。來看下面案例

let person = {
    getName: function() {
      return super.toString() // 報(bào)錯(cuò)
    }
}

在上面example中无午,person對象里用匿名function定義了一個(gè)屬性媒役,由于在當(dāng)前上下文中super引用是非法的,所以就拋出錯(cuò)誤宪迟。那么為什么同樣都是函數(shù)而有差異呢酣衷,那么我們繼續(xù)往下看。

正確區(qū)分方法的定義

在Es6之前沒有規(guī)定的方法這個(gè)概念次泽,方法僅僅是一個(gè)具有功能而非對象的屬性鸥诽,而在Es6中正式將方法定義為一個(gè)函數(shù)商玫,它會有一個(gè)內(nèi)部的[[HomeObject]]屬性來容納這個(gè)方法從屬的對象∧到瑁看下面例子

let person = {
    getName() {} // 是方法
}
function getName() {} // 不是方法

上面example中拳昌,定義person對象,它有一個(gè)getName方法钠龙,由于直接把函數(shù)賦值給了person對象炬藤,getName方法的[[HomeObject]]屬性值為person對象。然后在看下面用function關(guān)鍵字定義的getName方法碴里,這時(shí)它沒有賦值給一個(gè)對象沈矿,所以沒有明確定義[[HomeObject]]屬性。如果不使用super關(guān)鍵字這兩個(gè)函數(shù)這點(diǎn)小區(qū)別沒什么大問題咬腋。但是要使用super關(guān)鍵字的話就尤其重要羹膳。

因?yàn)?code>super關(guān)鍵字引用都通過[[HomeObject]]屬性來確定后續(xù)運(yùn)行過程。super關(guān)鍵字先會在[[HomeObject]]屬性上找到當(dāng)前對象(屬性值)根竿,也就是person然后在調(diào)用Object.getPrototypeOf方法獲取當(dāng)前原型陵像, 然后在去原型上找到當(dāng)前同名函數(shù),最后設(shè)置this綁定并且調(diào)用寇壳。這也就是上面為什么super關(guān)鍵字會報(bào)錯(cuò)的原因醒颖。

覺得寫的不錯(cuò)的話那就點(diǎn)個(gè)贊叭!


大家也可以加我的微信一起交流 這里

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壳炎,一起剝皮案震驚了整個(gè)濱河市泞歉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匿辩,老刑警劉巖腰耙,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異铲球,居然都是意外死亡沟优,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門睬辐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挠阁,“玉大人,你說我怎么就攤上這事溯饵∏炙祝” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵丰刊,是天一觀的道長隘谣。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么寻歧? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任掌栅,我火速辦了婚禮,結(jié)果婚禮上码泛,老公的妹妹穿的比我還像新娘猾封。我一直安慰自己,他們只是感情好噪珊,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布晌缘。 她就那樣靜靜地躺著,像睡著了一般痢站。 火紅的嫁衣襯著肌膚如雪磷箕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天阵难,我揣著相機(jī)與錄音岳枷,去河邊找鬼。 笑死呜叫,一個(gè)胖子當(dāng)著我的面吹牛空繁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怀偷,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼家厌,長吁一口氣:“原來是場噩夢啊……” “哼播玖!你這毒婦竟也來了椎工?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜀踏,失蹤者是張志新(化名)和其女友劉穎维蒙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體果覆,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颅痊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了局待。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斑响。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钳榨,靈堂內(nèi)的尸體忽然破棺而出舰罚,到底是詐尸還是另有隱情授药,我是刑警寧澤欢揖,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站仲智,受9級特大地震影響饼齿,放射性物質(zhì)發(fā)生泄漏饲漾。R本人自食惡果不足惜蝙搔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望考传。 院中可真熱鬧吃型,春花似錦、人聲如沸伙菊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镜硕。三九已至运翼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兴枯,已是汗流浹背血淌。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留财剖,地道東北人悠夯。 一個(gè)月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像躺坟,于是被迫代替她去往敵國和親沦补。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容