ES6 對象增強


  對象字面量語法擴展:

  1, 屬性初始化語法簡寫給一個屬性賦一個變量值,如果變量名和屬性名相同,可以省略變量名和冒號,直接寫屬性名,js引擎在執行代碼的時候,自動查找 和屬性命名相同的變量並賦值。

復制代碼
let x = 1, y = 2;
let object = { 
  x, // 屬性名是x,變量名也是x, 兩者一致,可以簡寫
  y
}; console.log(object.x); //output "1"
復制代碼

  2, 更為簡潔 的方法屬性定義:ES5的時候,把一個函數賦值給屬性的時候,函數必須是一個完整的函數定義

let object = {
    myFunction: function(){
        console.log("Hello World")  
    }  
}

  但是在ES6中,可以把:function 這一部分去掉了,寫法如下

let object = {
    myFunction(){
        console.log("Hello World")  
    }  
}

  語法確實簡潔多了,不過要注意一個特殊情況,只有給屬性賦值的是匿名函數的時候,才可以使用簡潔語法,如果賦值的是一個有名字的函數,那么就不能使用匿名函數了。如下情況就不能

let object = {
    myFunction: function hello(){
        console.log("Hello World")  
    }  
}

  函數hello 賦值給屬性myFunction, 你可能會問,為什么要給函數取一個hello 名字,最常見的一種情況是遞歸,自己調用自己,如果沒有名字,怎么調用?還有就是程序debugger 的時候,有函數名字可以直接定位, you don't know js 的作者就強烈建議書寫有名字的函數。

  3, 計算屬性名:ES5 的時候,對象字面量中的屬性都是事先定義好的, 不能使用變量,從而在程序運行的時候動態生成屬性,但在ES6中,這種情況改變了,對象字面量中可以存在動態生成的屬性,不過語法就要稍微變一下了,需要把動態屬性用[] 包括起來,這樣在程序運行的時候可以對[] 中的內容進行計算

let object = {
  ["first" + "Name"]: "Eden",
};

//extract
console.log(object["first" + "Name"]); //Output "Eden"

  4, 對重復屬性名的處理: 在ES5 的時候,如果給一個對象賦值為相同的屬性,它就會報錯。但在ES6 下,它不會報錯了,它會取最后一個相同屬性的值。

let obj = {
    name: 'Sam',
    name: 'Jason'
};
console.log(obj.name) // 'jason'

  新的方法

  1, Object.is() 方法:  判斷兩個數是否相等。你可能有點差異,不是有 == 和 === 來判斷相等了嗎,怎么還需要判斷相等的方法? 不用擔心,Object.is() 是用來處理極端情況的,比如NaN. NaN 和任何數都不相等,包含它本身,沒有辦法直接比較,現在就可以調用Object.is() 方法了,他就接受倆個要比較相等的參數。Object.is(NaN, NaN);  還有+0和-0, 對於js 引擎來說,他們兩個是不相等的,但是 用== 和=== 做判斷的時候,他們是相等的,為了解決這種問題,就可以使用Object.is(+0, -0) 

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

  對於Object.is () 來說,你可能發現,我們幾乎用不到它, 它就是對=== 操作符在某些極端情況下的糾正,所以對於比較,我們還是用== 或===, 平常怎么用就怎么用,只有碰到極端情況再用Object.is() 方法。 

  2, Object.assign(): 用於將所有可枚舉屬性的值從一個或多個源對象復制到目標對象。它將返回目標對象。Object.assign(target, ...sources),target 目標對象,sources: 源對象

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target); // Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget); // Object { a: 1, b: 4, c: 5 }

   3, Object.setPrototypeOf(), 設置一個對象的原型對象,它接受兩個參數,一個是對象,一個是對象要鏈接到的原型對象 。Object.setPrototypeOf(obj, prototypeObj).

let person = {
    greeting() {
        return "hello";
    }
}

let dog = {
    greeting() {
        return "woof";
    }
}

let obj = {};

// obj 鏈接到person 
Object.setPrototypeOf(obj, person);
console.log(obj.greeting()); // "hello"
// obj 鏈接到dog
Object.setPrototypeOf(obj, dog);
console.log(obj.greeting()); // woof

  通過Object.setPrototypeOf() 方法可以動態地改變一個對象的原型對象。這里簡單說一下對象的原型,在js中沒有所謂的類式繼承,因為js中沒有java  中的類, 那Js中有什么呢? 它只有對象,當我們把一個對象鏈接到原型對象上的時候,它是對象和對象之間的關系,就像上面中的代碼一樣, obj 就一個對象,它的原型對象無論是person, 還是dog, 也是普通的對象, 對象和對象的鏈接關系,就像火車的車廂

通過鏈條鏈接起來一樣, 把每一個車廂想象成每一個對象。為什么把對象鏈接起來呢? 因為另外一個對象有我們想要的方法,比如上面的greeting 方法。我們剛剛聲明了一個對象obj,  空對象,什么都沒有,剛要給他聲明一個greeting 方法,突然發現person  對象有這個方法,那就不要聲明了,拿過來用就可以了,這不,這兩個對象就有必要鏈接到一起了。但執行obj.greeting()的時候,發現obj對象上並沒有這個方法,但是發現它鏈接到一個對象person, 那就順着鏈條繼續找吧,正好,person 對象上有這個方法,就調用了person 對象上的方法。就像火車上找人一樣,你先從第一車廂開始,沒有,因為第一車廂和第二車廂鏈接起來了,你就到第二車廂去找,還是沒有,第二車廂又和第三車廂鏈接到一起,你就去第三車廂去找,找到了,如果沒有找到,繼續第四車廂,因為每一個車廂都是鏈接起來的。如果所有的車廂都找完了,還是沒有,那就真沒有了。

  那我們還能不能在obj上面定義一個greeting 方法,因為有時候原型對象上的方法不能完全滿足要求?可以,當我們在一個對象上定義一個方法的時候,它就不會就找原型鏈了,直接調用對象上面的方法。

let obj = {
    greeting() {
        return 'obj';
    }
};

  但有時候, 你發現,在obj 對象中定義的方法,可能使用到原型對象上的同名方法, 只要調用原型對象上面的方法再進行一下組裝就可以達到要求了。ES6 提供了super 關鍵詞,它就指向原型對象

let obj = {
    greeting() {
        return super.greeting()  + 'obj';
    }
};

  這里要注意的是,對象方法的定義只能使用簡潔的語法形式,否則報錯。

  super 是怎么實現的呢?在ES6 中,如果一個對象中定義了方法,這個方法自動獲取到一個內置的屬性[[HomeObject]], 來指向這個對象。super 呢,就是通過Object.getPrototypeOf([[HomeObject]]) 來獲取到原型對象。obj.greeting() greeting() 方法中的[[HomeObject]] 就指向了obj.  那里面的super 就是Object.getPrototypeOf(obj), 那就是person 或dog 了,super.greeting() 就相當於person.greeting()了, 更為准確的說是 person.greeting.call(this).  因為如果person中的greenting有this, 我們還要給它指定this 指向, 不能讓里面的this 指向別的對象, 只能讓this 指向 obj 了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM