摘要:通過字面量語法擴展新增方法改進原型等多種方式加強對象的使用,并通過解構簡化對象的數據提取過程。四解構賦值為數組和對象字面量提供了新特性解構,可以簡化數據提取的過程,減少同質化的代碼。
ES6 通過字面量語法擴展、新增方法、改進原型等多種方式加強對象的使用,并通過解構簡化對象的數據提取過程。一、字面量語法擴展
在 ES6 模式下使用字面量創建對象更加簡潔,對于對象屬性來說,屬性初始值可以簡寫,并可以使用可計算的屬性名稱。對象方法的定義消除了冒號和 function 關鍵字,示例如下:
// Demo1 var value = "name", age = 18 var person = { age, // age: age ["my" + value]: "Jenny", // myname sayName () { // sayName: function() console.log(this.myname) } } console.log(person.age) // 18 console.log(person.myname) // Jenny person.sayName(); // Jenny
針對重復定義的對象字面量屬性,ES5嚴格模式下會進行重復屬性檢查從而拋出錯誤,而ES6移除了這個機制,無論嚴格模式還是非嚴格模式,同名屬性都會取最后一個值。
// demo2 var person = { ["my" + value]: "Jenny", myname: "Tom", myname: "Lee", } console.log(person.myname) // Lee二、新增方法
從 ES5 開始遵循的一個設計目標是,避免創建新的全局函數,也不在object.prototype上創建新的方法。2.1 Object.is( )
為了是某些任務更容易實現,ES6 在全局 Object 對象上引入一些新的方法。
ES6 引入Object.is()方法來彌補全等運算符的不準確計算。
全等運算符在比較時不會觸發強制轉換類型,Object.is()運行結果也類似,但對于 +0 和 -0(在 JS 引擎中為兩個不同實體)以及特殊值NaN的比較結果不同,示例來看:
// demo3 console.log(5 == "5") // true console.log(5 === "5") // false console.log(Object.is(5, "5")) // false 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
總結來說,Object.is()對所有值進行了更嚴格等價判斷。當然,是否使用Object.is()代替全等操作符(===)取決于這些特殊情況是否影響代碼。
2.2 Object.assign( )ES6 添加Object.assign()來實現混合(Mixin)模式,即一個對象接收另一個對象的屬性和方法。注意是接收而不是繼承,例如接收 demo1 中的對象:
// demo4 var friend = {} Object.assign(friend, person) friend.sayName() // Jenny console.log(friend.age) // 18 console.log(Object.getPrototypeOf(friend) === person) // false
在Object.assign()之前,許多 JS 庫自定義了混合方法 mixin( ) 來實現對象組合,代碼類似于:
function mixin(receiver, supplier) { Object.keys(supplier).forEach(function (key) { receiver[key] = supplier[key] }) return receiver }
可以看出 mixin( ) 方法使用“=”賦值操作,并不能復制訪問器屬性,同理Object.assign()也不能復制訪問器屬性,只是執行了賦值操作,訪問器屬性最終會轉變為接收對象的數據屬性。示例如下:
// demo5 var animal = { name: "lili", get type () { return this.name + type }, set type (news) { type = news } } animal.type = "cat" console.log(animal.type) // lilicat var pet = {} Object.assign(pet, animal) console.log(animal) // { name: "lili", type: [Getter/Setter] } console.log(pet) // { name: "lili", type: "lilicat" }2.3 Object.setPrototypeOf( )
正常情況下對通過構造函數或Object.create()創建時,原型是被指定的。ES6 添加Object.setPrototypeOf() 方法來改變對象的原型。
例如創建一個繼承 person 對象的 coder 對象,然后改變 coder 對象的原型:
// demo6 let person = { myname: "Jenny", sayName () { console.log(this.myname) } } // 創建原型為 person 的 coder 對象 let coder = Object.create(person) coder.sayName() // Jenny console.log(Object.getPrototypeOf(coder) === person) // true let hero = { myname: "lee", sayName () { console.log(this.myname) } } // 改變 coder 對象的原型為 hero Object.setPrototypeOf(coder, hero) coder.sayName() // lee console.log(Object.getPrototypeOf(coder) === hero) // true
對象原型被存儲在內部專有屬性[[Prototype]],調用Object.getPrototypeOf()返回存儲在其中的值,調用Object.setPrototypeOf()改變其值。這個方法加強了對對象原型的操作,下一節重點講解其它操作原型的方式。
三、增強對象原型原型是 JS 繼承的基礎,ES6 針對原型做了很多改進,目的是更靈活地方式使用原型。除了新增的Object.setPrototypeOf()改變原型外,還引入Super關鍵字簡化對原型的訪問,
3.1 Super關鍵字ES6 引入Super來更便捷的訪問對象原型,上一節介紹 ES5 可以使用Object.getPrototypeOf()返回對象原型。舉例說明Super的便捷,當對象需要復用原型方法,重新定義自己的方法時,兩種實現方式如下:
// demo7 let coder1 = { getName () { console.log("coder1 name: ") Object.getPrototypeOf(this).sayName.call(this) } } // 設置 coder1 對象的原型為 hero(demo6) Object.setPrototypeOf(coder1, hero) coder1.getName() // coder1 name: lee let coder2 = { getName () { console.log("coder2 name: ") super.sayName() } } Object.setPrototypeOf(coder2, hero) coder2.getName() // coder2 name: lee
在 coder1 對象的 getName 方法還需要call(this)保證使用的是原型方法的 this,比較復雜,并且在多重繼承會出現遞歸調用棧溢出錯誤,而直接使用Super就很簡單安全。
注意必須在簡寫方法中使用Super,要不然會報錯,例如以下代碼運行語法錯誤:
let coder4= { getName: function () { // getName () 正確 super.sayName() // SyntaxError: "super" keyword unexpected here }
因為在例子中 getName 成為了匿名 function 定義的屬性,在當前上下問調用Super引用是非法的。如果不理解,可以進一步看下方法的從屬對象。
3.2 方法的從屬對象ES6 之前“方法”是具有功能而非數據的對象屬性,ES6 正式將方法定義為有 [[HomeObject]]內部屬性的函數。
[[HomeObject]]屬性存儲當前方法的從屬對象,例如:
let coder5 = { sayName () { console.log("I have HomeObject") } } function shareName () { console.log("No HomeObject") }
coder5 對象的 sayName( ) 方法的[[HomeObject]]屬性值為 coder5,而 function 定義的 shareName( ) 沒有將其賦值給對象,所以沒有定義其[[HomeObject]]屬性,這在使用Super時很重要。
Super就是在[[HomeObject]]屬性上調用Object.getPrototypeOf()獲得原型的引用,然后搜索原型得到同名函數,最后設置 this 綁定調用相應方法。
四、解構賦值ES6 為數組和對象字面量提供了新特性——解構,可以簡化數據提取的過程,減少同質化的代碼。解構的基本語法示例如下:
let user = { name: "jenny", id: 18 } let {name, id} = user console.log(name, id) // jenny 18
注意在這段代碼中,user.name 存儲在與對象屬性名同名的 name 變量中。
4.1 默認值如果解構時變量名稱與對象屬性名不同,即在對象中不存在,那么這個變量會默認為undefined:
let user = { name: "jenny", id: 18 } let {name, id, job} = user console.log(name, id, job) // jenny 18 undefined4.2 非同名變量賦值
非同名變量的默認值為undefined,但更多時候是需要為其賦值的,并且會將對象屬性值賦值給非同名變量。ES6 為此提供了擴展語法,與對象字面量屬性初始化程序很像:
let user = { name: "jenny", id: 18 } let {name, id = 16, job = "engineer"} = user console.log(name, id, job) // jenny 18 engineer let {name: localName, id: localId} = user console.log(localName, localId) // jenny 18 let {name: otherName = "lee", job: otherJob = "teacher"} = user console.log(otherName, otherJob) // jenny teacher
可以看出這種語法實際與對象字面量相反,賦值名在冒號左,變量名在右,并且解構賦值時,只是更新了默認值,不能覆蓋對象原有的屬性值。
4.3 嵌套解構解構嵌套對象的語法仍然類似對象字面量,使用花括號繼續查找下層結構:
let user = { name: "jenny", id: 18, desc: { pos: { lng: 111, lat: 333 } } } let {desc: {pos}} = user console.log(pos) // { lng: 111, lat: 333 } let {desc: {pos: {lng}}} = user console.log(lng) // 111 let {desc: {pos: {lng: longitude}}} = user console.log(longitude) // 111五、對象類別
ES6 規范定義了對象的類別,特別是針對瀏覽器這樣的執行環境。
普通(Ordinary)對象
具有 JS 對象所有的默認內部行為
特異(Exotic)對象
具有某些與默認行為不符的內部行為
標準(Standard)對象
ES6 規范中定義的對象
可以是普通對象或特異對象,例如 Date、Array 等
內建對象
腳本開始執行時存在于 JS 執行環境中的對象
所有標準對象都是內建對象
推薦閱讀《深入理解ES6》
加油哦,少年~文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98500.html
摘要:比如上面展示的情況都是可以聯合使用的比如對象的解構賦值對象的解構賦值是基于屬性的。當給已存在的變量解構賦值時,注意加這是由于如果不加會把左邊看成一個代碼塊,會報錯。注意事項數組的解構賦值中,使用的變量必須放在最后。 解構賦值 解構賦值是一個聽起來比較高大上的特性,但按我的理解,它就是一種語法糖。它并沒有賦予js更強大的能力,只是讓賦值操作更加的靈活,效率。 在es6之前,賦值操作需要=...
摘要:變量的解構賦值數組的解構賦值允許寫成下面這樣本質上,這種寫法屬于模式匹配,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。對象的解構賦值對象的解構與數組有一個重要的不同。由于和無法轉為對象,所以對他們進行解構賦值,都會報錯。 變量的解構賦值 數組的解構賦值 let a = 1; let b = 2; let c = 3; ES6允許寫成下面這樣 let [a,b,c] = [1,...
摘要:解構是新加的解構功能,可以使得我們獲取數據更方便,從而提高日常編碼效率。解構賦值的語法要求,一定要用一對小括號包裹整個解構賦值表達式。當然,也有辦法定義不同命中的變量,依然利用解構獲得對象的屬性值。下一篇,我們講解構在類型數據上的解構。 解構是ES6新加的解構功能,可以使得我們獲取數據更方便,從而提高日常編碼效率。解構可以用于對象,也可以用于數組,這篇文章我們只講在對象類型上使用解構可...
摘要:另外對于已經聲明的變量進行解構賦值時,要非常小心。因此在行首加,將其強制轉化為表達式執行。由于和無法轉為對象,所以對它們進行解構賦值,都會報錯。 let和const let和const是es6新增的兩個變量聲明關鍵字,與var的不同點在于: (1)let和const都是塊級作用域,在{}內有效,這點在for循環中非常有用,只在循環體內有效。var為函數作用域。 (2)使用let和con...
摘要:前言前言該篇筆記是第二篇變量的解構賦值。這一章原文鏈接變量的解構賦值解構賦值解構賦值允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構。對象的解構賦值是根據對象值進行匹配。前言該篇筆記是第二篇 變量的解構賦值。這一章原文鏈接: 變量的解構賦值解構賦值ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)。解構賦值是對賦值運...
閱讀 3149·2021-11-22 13:54
閱讀 3435·2021-11-15 11:37
閱讀 3598·2021-10-14 09:43
閱讀 3496·2021-09-09 11:52
閱讀 3595·2019-08-30 15:53
閱讀 2457·2019-08-30 13:50
閱讀 2054·2019-08-30 11:07
閱讀 885·2019-08-29 16:32