摘要:通過多種方式來加強(qiáng)對象的使用,通過簡單的語法擴(kuò)展,提供更多操作對象及與對象交互的方法。增強(qiáng)對象原型改變對象的原型正常情況下,無論是通過構(gòu)造函數(shù)還是方法創(chuàng)建對象,其原型是在被創(chuàng)建時指定的。引用相當(dāng)于指向?qū)ο笤偷闹羔?/p>
ES6通過多種方式來加強(qiáng)對象的使用,通過簡單的語法擴(kuò)展,提供更多操作對象及與對象交互的方法。
對象字面量語法擴(kuò)展 對象屬性初始值的簡寫ES5中初始化屬性值的方式:
function createPerson(name, age) { return { name: name, age: age }; }
這段代碼中的createPerson()函數(shù)創(chuàng)建的對象,其屬性名與函數(shù)的參數(shù)相同,在返回的結(jié)果中,name和age分別重復(fù)了兩遍,只是其中一個是對象屬性名,另一個是為屬性賦值的變量。
ES6中可以簡單地只寫屬性名即可:
function createPerson(name, age) { return { name, age }; }
當(dāng)對象字面量里只有一個屬性的名稱時,JavaScript引擎會在可訪問作用域中查找同名變量;如果找到,則該變量的值被賦給對象字面量的同名屬性。
對象方法的簡寫ES5中定義對象方法:
var person = { name: "Nicholas", sayName: function() { console.log(this.name); } };
ES6中簡寫后的對象方法:
var person = { name: "Nicholas", sayName() { console.log(this.name); } };
二者唯一的區(qū)別是,簡寫方法可以使用super關(guān)鍵字(稍后會討論)。
可計(jì)算屬性名ES5中,如果想要通過計(jì)算得到屬性名,就需要使用方括號代替點(diǎn)記法,請看:
var person = {}; lastName = "last name"; person["first name"] = "Nicholas"; person[lastName] = "Zakas"; console.log(person["first name"]); // "Nicholas" console.log(person[lastName]); // "Zakas"
ES5在對象字面量中,也可以直接使用字符串字面量作為屬性名:
var person = { "first name": "Nicholas" }; console.log(person["first name"]); // "Nicholas"
這種模式適用于屬性名提前已知或可被字符串字面量表示的情況。然而,如果屬性名"first name"被包含在一個變量中(就像之前的示例中的那樣),或者需要通過計(jì)算才能得到該變量的值,那么ES5中是無法為一個對象字面量定義該屬性的。
而在ES6中,可在對象字面量中使用可計(jì)算屬性名,請看:
let lastName = "last name"; let person = { "first name": "Nicholas", [lastName]: "Zakas" }; console.log(person["first name"]); // "Nicholas" console.log(person[lastName]); // "Zakas"
在對象字面量中使用方括號表示該屬性名是可計(jì)算的,它的內(nèi)容將被求值并最終轉(zhuǎn)化為一個字符串,因而同樣可以使用表達(dá)式作為屬性的可計(jì)算名稱,例如:
var suffix = " name"; var person = { ["first" + suffix]: "Nicholas", ["last" + suffix]: "Zakas" }; console.log(person["first name"]); // "Nicholas" console.log(person["last name"]); // "Zakas"新增方法 Object.is()方法
當(dāng)你想在JavaScript中比較兩個值時,可能習(xí)慣于使用相等運(yùn)算符(==)或全等運(yùn)算符(===),許多開發(fā)者更喜歡后者,從而避免在比較時觸發(fā)強(qiáng)制類型轉(zhuǎn)換的行為。但即使全等運(yùn)算符也不完全準(zhǔn)確,比如+0和-0在JavaScript引擎中被表示為兩個完全不同的實(shí)體,而如果使用全等運(yùn)算符===對兩者進(jìn)行比較,得到的結(jié)果是兩者相等;同樣,NaN===NaN的返回值為false,需要使用isNaN()方法才可以正確檢測NaN。
ES6引入了Object.is()方法來彌補(bǔ)全等運(yùn)算符的不準(zhǔn)確運(yùn)算。請看示例:
console.log(+0 == -0); // true 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 consolog.log(5 == 5); // true consolog.log(5 == "5"); // true consolog.log(5 === 5); // true consolog.log(5 === "5"); // false console.log(Object.is(5, 5)); // true console.log(Object.is(5, "5")); // false
對于Object.is()方法來說,其運(yùn)行結(jié)果在大部分情況下與===運(yùn)算符相同,唯一的區(qū)別在于+0和-0被識別為不相等并且NaN與NaN等價(jià)。但是你大可不必拋棄等號運(yùn)算符,是否選擇使用Object.is()方法而不是===取決于那些特殊情況如何影響代碼。
Object.assign()方法混合(Mixin)是JavaScript種實(shí)現(xiàn)對象組合最流行的一種模式。在一個mixin方法中,一個對象接收來自另一個對象的屬性和方法,許多JavaScript庫中都有類似minxin方法:
function mixin(receiver, supplier) { Object.keys(supplier).forEach(function(key) { receiver[key] = supplier[key]; }); return receiver; }
mixin()函數(shù)遍歷supplier的自有屬性并復(fù)制到receiver中(復(fù)制行為是淺復(fù)制,當(dāng)屬性值為對象時只復(fù)制對象的引用)。這樣一來,receiver不通過繼承就可以獲得新屬性,請參考這段代碼:
function EventTarget() { ... } EventTarget.prototype = { constructor: EventTarget, emit: function() { ... }, on: function() { ... } }; var myObject = {}; mixin(myObject, EventTarget.prototype); myObject.emit("somethingChanged");
這種混合模式非常流行,因而ES6添加了Object.assign()方法來實(shí)現(xiàn)相同的功能:
Object.assign(myObject, EventTarget.prototype);
Object.assign()方法接受一個接收對象和任意數(shù)量的源對象,最終返回接收對象。如果多個源對象具有相同屬性,則排位靠后的會覆蓋排位靠前的。
需要注意的是,Object.assign()方法不能將提供者的訪問器屬性復(fù)制到接收對象中。由于Object.assign()方法執(zhí)行了賦值操作,因此提供者的訪問器屬性最終會轉(zhuǎn)變?yōu)榻邮諏ο笾械囊粋€數(shù)據(jù)屬性,請看示例:
var receiver = {}, supplier = { get name() { return "file.js"; } }; Object.assign(receiver, supplier); var descriptor = Object.getOwnPropertyDescriptor(receiver, "name"); console.log(descriptor.value); // "file.js" console.log(descriptor.get); // undefined
在這段代碼中,supplier有一個名為name的訪問器屬性。當(dāng)調(diào)用Object.assign()方法時返回字符串"file.js",因此receiver接收這個字符串后將其存為數(shù)據(jù)屬性receiver.name。
增強(qiáng)對象原型 改變對象的原型正常情況下,無論是通過構(gòu)造函數(shù)還是Object.create()方法創(chuàng)建對象,其原型是在被創(chuàng)建時指定的。對象原型在實(shí)例化之后保持不變,直到ES5都是JavaScript編程最重要的設(shè)定之一,雖然在ES5中添加了Object.getPrototypeOf()方法來返回任意指定對象的原型,但仍缺少對象在實(shí)例化后改變原型的標(biāo)準(zhǔn)方法。
所以,在ES6中添加了Object.setPrototypeOf()方法來改變這一現(xiàn)狀:
let person = { getGreeting() { return "Hello"; } }; let dog = { getGreeting() { return "Woof"; } }; // 以person對象為原型 let friend = Object.create(person); console.log(friend.getGreeting()); // "Hello" console.log(Object.getPrototypeOf(friend) === person); // true // 將原型設(shè)置為dog console.log(friend.getGreeting()); // "Woof" console.log(Object.getPrototypeOf(friend) === dog); // true
這段代碼定義了兩個基對象:person和dog。二者多有getGreeting()方法。friend對象先繼承person對象,調(diào)用getGreeting()方法輸出"Hello";當(dāng)原型被變更為dog對象時,原先與person對象的關(guān)聯(lián)被解除,調(diào)用person.getGreeting()方法時輸出的內(nèi)容就變?yōu)榱?Woof"。
對象原型的真實(shí)值被存儲在內(nèi)部專用屬性[[Prototype]]中,調(diào)用Object.getPrototypeOf()方法返回存儲在其中的值,調(diào)用Object.setPrototypeOf()方法改變其中的值。然而,這不是操作[[Prototype]]值的唯一方法。
用super簡化原型訪問ES6引入了super引用的特性,使用它可以更便捷地訪問對象原型。舉個例子,如果你想重寫對象實(shí)例方法,又需要調(diào)用與它同名的原型方法,先看看ES5中的實(shí)現(xiàn):
let person = { getGreeting() { return "Hello"; } }; let dog = { getGreeting() { return "Woof"; } }; let friend = { getGreeting() { return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!"; } }; // 將原型設(shè)置為`person` Object.setPrototypeOf(friend, person); console.log(friend.getGreeting()); // "Hello, hi!" console.log(Object.getPrototypeOf(friend) === person); // true // 將原型設(shè)置為`dog` Object.setPrototypeOf(friend, dog); console.log(friend.getGreeting()); // "Woof, hi!" console.log(Object.getPrototypeOf(friend) === dog); // true
在這個示例中,friend對象的getGreeting()方法調(diào)用了同名的原型方法。Object.getPrototypeOf()方法可以確保調(diào)用正確的原型,并向輸出字符串疊加另一個字符串;后面的.call(this)可以確保正確設(shè)置原型方法中的this值。
要準(zhǔn)確記得如何使用Object.getPrototypeOf()方法和.call(this)方法來調(diào)用原型上的方法實(shí)在有些復(fù)雜,所以ES6引入了super關(guān)鍵字。super引用相當(dāng)于指向?qū)ο笤偷闹羔槪?/p>
let friend = { getGreeting() { // return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!"; return sper.getGreeting() + ", hi!"; } };
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85178.html
摘要:使得聲明對象字面量更加簡單,提供了屬性簡寫和方法簡寫功能,屬性名計(jì)算的新特性。屬性簡寫在及以前的版本中,對象字面量只支持鍵值對集合。實(shí)際業(yè)務(wù)中,對象字面量的初始化會有一定的代碼重復(fù)。 showImg(https://segmentfault.com/img/bVWd8N?w=320&h=235); ECMAScript6使得聲明對象字面量更加簡單,提供了屬性簡寫和方法簡寫功能,屬性名計(jì)...
摘要:精致從細(xì)節(jié)做起。標(biāo)準(zhǔn)會在每年的月發(fā)布一次,作為當(dāng)年的正式版本,便是年發(fā)布的正式版本。支持情況各大瀏覽器對的支持情況瀏覽器支持情況對的支持情況支持情況。在瀏覽器中基于實(shí)現(xiàn)的已經(jīng)成為的重要組成部分。 精致從細(xì)節(jié)做起。前端的工作也有一段時間了,大大小小的前端框架都有接觸過,越是深入學(xué)習(xí)越是感覺之前的學(xué)習(xí)過于粗糙,基礎(chǔ)不夠扎實(shí),于是準(zhǔn)備近期把JavaScript的基礎(chǔ)知識點(diǎn)梳理一下,查缺補(bǔ)漏,...
摘要:采用二八定律,主要涉及常用且重要的部分。對象是當(dāng)前模塊的導(dǎo)出對象,用于導(dǎo)出模塊公有方法和屬性。箭頭函數(shù)函數(shù)箭頭函數(shù)把去掉,在與之間加上當(dāng)我們使用箭頭函數(shù)時,函數(shù)體內(nèi)的對象,就是定義時所在的對象,而不是使用時所在的對象。 ES6 原文博客地址:https://finget.github.io/2018/05/10/javascript-es6/ 現(xiàn)在基本上開發(fā)中都在使用ES6,瀏覽器環(huán)境...
摘要:代表基本上是常規(guī)。第次更新,在年完成。幾乎完全支持所有主要的瀏覽器。但這將是一段時間,直到較舊版本的瀏覽器逐步停止使用。這意味著將轉(zhuǎn)換為。在組件的情況下,寫入的將如下所示在我們在第一個作出反應(yīng)組件使用的語法是語法。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3797原文:https://www.fullstackreact....
摘要:原型會自動調(diào)整,通過調(diào)用方法即可訪問基類的構(gòu)造函數(shù)。在簡單情況下,等于類的構(gòu)造函數(shù)的值是輸出這段代碼展示了當(dāng)調(diào)用時等于。 大多數(shù)面向?qū)ο缶幊陶Z言都支持類和類繼承的特性,而JavaScript只能通過各種特定方式模仿并關(guān)聯(lián)多個相似的對象。這個情況一直持續(xù)到ES5。由于類似的庫層出不窮,最終ES6引入了類特性,統(tǒng)一了類和類繼承的標(biāo)準(zhǔn)。 ES5模仿類 先看一段ES5中模仿類的代碼: func...
閱讀 1003·2023-04-26 01:47
閱讀 1683·2021-11-18 13:19
閱讀 2050·2019-08-30 15:44
閱讀 665·2019-08-30 15:44
閱讀 2306·2019-08-30 15:44
閱讀 1242·2019-08-30 14:06
閱讀 1429·2019-08-30 12:59
閱讀 1907·2019-08-29 12:49