一、字面量語法擴展


在 ES6 模式下使用字" />

ES6 對象的新功能與解構賦值介紹

 更新時間:2019-02-06 22:00:21   作者:佚名   我要評論(0)

ES6 通過字面量語法擴展、新增方法、改進原型等多種方式加強對象的使用,并通過解構簡化對象的數據提取過程。


一、字面量語法擴展


在 ES6 模式下使用字

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上創建新的方法。

為了是某些任務更容易實現,ES6 在全局 Object 對象上引入一些新的方法。

2.1 Object.is( )

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 undefined

4.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基礎學習之解構賦值
  • 基于ES6作用域和解構賦值詳解
  • ES6解構賦值的功能與用途實例分析
  • ES6解構賦值實例詳解
  • es6中的解構賦值、擴展運算符和rest參數使用詳解
  • ES6新特性四:變量的解構賦值實例
  • ES6學習之變量的解構賦值
  • 解析JavaScript的ES6版本中的解構賦值

相關文章

  • Tensorflow分類器項目自定義數據讀入的實現

    Tensorflow分類器項目自定義數據讀入的實現

    在照著Tensorflow官網的demo敲了一遍分類器項目的代碼后,運行倒是成功了,結果也不錯。但是最終還是要訓練自己的數據,所以嘗試準備加載自定義的數據,然而d
    2019-02-06
  • ES6 對象的新功能與解構賦值介紹

    ES6 對象的新功能與解構賦值介紹

    ES6 通過字面量語法擴展、新增方法、改進原型等多種方式加強對象的使用,并通過解構簡化對象的數據提取過程。 一、字面量語法擴展 在 ES6 模式下使用字
    2019-02-06
  • Redis連接錯誤的情況總結分析

    Redis連接錯誤的情況總結分析

    前言 最近由于流量增大,redis 出現了一連串錯誤,比如: LOADING Redis is loading the dataset in memory use of closed network connection connec
    2019-02-06
  • 使用TensorFlow實現二分類的方法示例

    使用TensorFlow實現二分類的方法示例

    使用TensorFlow構建一個神經網絡來實現二分類,主要包括輸入數據格式、隱藏層數的定義、損失函數的選擇、優化函數的選擇、輸出層。下面通過numpy來隨機生成一
    2019-02-06
  • PHP實現字符串大小寫轉函數的功能實例

    PHP實現字符串大小寫轉函數的功能實例

    字符串的大小寫轉換功能在日常中經常使用。那么如何實現一個簡單的大小寫轉換功能呢? 在php中,最終使用的是c語言的toupper,tolower函數將字符進行大小寫
    2019-02-06
  • Nginx代理時header頭中帶"_"信息丟失問題的解決

    Nginx代理時header頭中帶"_"信息丟失問題的解決

    前言 開發網關項目時,在請求時往請求頭header中放入了簽名sign_key信息,在接收請求時再從header中拿出,在本地調試時是可以的,但上線之后通過Nginx代理之后
    2019-02-06
  • Python實現E-Mail收集插件實例教程

    Python實現E-Mail收集插件實例教程

    __import__函數 我們都知道import是導入模塊的,但是其實import實際上是使用builtin函數import來工作的。在一些程序中,我們可以動態去調用函數,如果我們
    2019-02-06
  • C++類中的特殊成員函數示例詳解

    C++類中的特殊成員函數示例詳解

    前言 C++類中有幾個特殊的非靜態成員函數,當用戶未定義這些函數時,編譯器將給出默認實現。C++11前有四個特殊函數,C++11引入移動語義特性,增加了兩個參數為
    2019-02-06
  • C++中的函數修飾符深入講解

    C++中的函數修飾符深入講解

    前言 C++博大精深,而且不斷擁抱新的變化。本文簡要總結一下C++中函數的修飾符,其中部分在實際中極少用到。 按修飾符的位置分為函數名前與函數名后兩種,以下
    2019-02-06
  • go實現文件的創建、刪除與讀取示例代碼

    go實現文件的創建、刪除與讀取示例代碼

    文件目錄的創建和刪除 package main import( "fmt" "os" ) func main(){ //創建目錄和權限 os.Mkdir("./benben",0777) //創建多級目錄和設置權限
    2019-02-06

最新評論

黑龙江新11选5开奖结果