首先,在JavaScript中物件是個很重要的概念,因為在JavaScript中一切都是物件,無論是函式,還是陣列。同樣,ES6這次也帶來了一些新特性。能夠幫助我們更加輕鬆與準確的完成想要完成的目標。
物件字面量語法擴充
物件字面量屬性簡寫
在ES6之前。我們使用字面量建立屬性,會寫一個屬性名,後面跟一個":",最後跟著屬性值。看起來一切都是很簡潔的,但是在屬性值與屬性名同名時,這就很痛苦了,每次都要寫兩個同樣的文字。我們看個例子:
let Person = function(name,age){
return {
name : name,
age : age,
}
}
複製程式碼
一個兩個這種程式碼沒問題,但是當類似的程式碼量一旦多起來,那便是很痛苦的一件事了。但是,在ES5中,這個問題將得到解決。它為我們提供了簡寫方式。
let Person = function(name,age){
return {
name,
age,
}
}
複製程式碼
在使用字面量的時候,我們只需寫一個變數名就好,剩下的工作由JavaScript引擎幫我們去做。JavaScript引擎回去可訪問作用域查詢同名屬性,找到便會將該變數的值賦值給字面量物件的同名屬性。如果沒找到,這個屬性的值為undefined。
物件字面量的可計算屬性名
在ES6之前,我們可以在物件建立之後,使用可計算屬性名,但是無法在物件字面量中使用可計算屬性名。現在ES6將可計算屬性名帶到了物件字面量中。
// ES6之前
let param1 = 'name';
let person = {};
person[param1] = 'kidd';
console.log(person[name]); // kidd
//不允許
let dog = {
[param]:'Snoopy',
}
// ES6
let firstName = 'first Name';
let cat = {
[firsName]:'tom'
}
console.log(cat[firstName]); // tom
複製程式碼
物件方法的簡寫
這不是一個重大的改進。但是能幫助我們書寫起來更容易。
// ES6之前按
let person= {
getName:function(){
return : this.name
}
}
// ES6
let person = {
getName(){
return this.name;
}
}
複製程式碼
重複的物件字面量屬性
在ES5及之前,我們如果在物件字面量中宣告瞭兩個同名屬性,嚴格模式下便會報錯。而ES6中將這個特性改變了,無論是否在嚴格模式下,物件字面量中宣告瞭兩個同名屬性,之後後面的屬性會生效。
let person = {
getName(){
return 'tom';
},
getName(){
return 'jure';
}
}
person.getName(); // jure
複製程式碼
物件自有屬性的列舉順序
在ES6之前自由屬性的列舉順序基本都是百家爭鳴,不同的JavaScript引擎,都會有不同的列舉順序,這次ES6算是將自由屬性的列舉順序給出了官方說法
- 所有數字鍵按照升序排列
- 所有字串鍵按照它們被加入物件的順序排列
- 所有symbol鍵按照它們被加入物件的順序排列
物件新增方法
在ES6也給物件新增了一些方法,下面讓我們來看看
Object.is()
Object.is()很想一個完整版的 “===”,因為它大部分情況下與 “===” 相同,只有兩種情況與 “===” 有一些差別。就是下面兩種情況
console.log(-0 === +0); //true
console.log(Object.is(+0,-0)); //false
console.log(NaN === NaN); //false
console.log(NaN,NaN); //true
複製程式碼
除了上面兩種情況,與 “===”是一樣的。
Object.assign()
因為很多JavaScript第三方庫有混合模式,這次ES6便將它們直接引入進來。assign方法的主要作用是將一個物件的方法、屬性複製給另一個物件。注意,這裡的複製其實是淺複製,如果被複制物件的屬性值是一個物件的話,那麼便只是將這個物件的引用複製給被複制物件。
function EventTarget(){ doSomething };
EventTarget.prototype = {
constructor : EventTarget,
emit : function(){ doSomething },
on : function(){ doSomething }
}
var obj = {},
Object.assign(obj,EventTarget.prototype);
obj.on();
複製程式碼
這樣的話,新建立的物件就會擁有之前物件的屬性。而且assign是可以接受任意數量的源物件的。如果不同的源物件中有同名屬性,最後被複制物件中會採用最有一個擁有此屬性的物件的屬性值。 還有一個很重要的點。assign是不能複製訪問器屬性的。如果源物件中有訪問器屬性,會在新的物件中變為數值屬性。
增強物件原型
我們都知道,JavaScript最特別的地方就是使用了原型繼承的方式。而現在,ES6對物件原型又進行了增強。
Super引用
super引用其實就是儲存了當前物件的原型物件的引用,在ES6之前,我們要獲得物件的原型只有通過Object.getPrototypeOf(this)的方法去返回原型物件。但是這個方法在某些情況的時候會發生某些錯誤,比如
let person = {
getGreeting(){
return 'Hello';
}
};
let friend = {
getGreeting(){
return Object.getPrototypeOf(this).getGreeting.call(this) + ", Hi!";
}
}
Object.setPrototypeOf(friend,person);
let relative = Object.create(friend);
console.log(person.getGreeting()); // Hello
console.log(friend.getGreeting()); // Hello, Hi!
console.log(relative.getGreeting()); // error
複製程式碼
這裡的問題是陷入了一個呼叫死迴圈,this是relative時Object.getPrototypeOf(this)返回的物件是friend。而Object.getPrototypeOf(this).getGreeting會呼叫friend的getGreeting()方法。後面的call(this)又會去改變當前的函式作用域,因此,陷入了一個遞迴呼叫的死迴圈,最後棧溢位報錯,但是在ES6中使用super就會解決這個問題
let person = {
getGreeting(){
return 'Hello';
}
};
let friend = {
getGreeting(){
return super.getGreeting() + ", Hi!";
}
}
Object.setPrototypeOf(friend,person);
let relative = Object.create(friend);
console.log(person.getGreeting()); // Hello
console.log(friend.getGreeting()); // Hello, Hi!
console.log(relative.getGreeting()); // Hello, Hi!
複製程式碼
這是因為super引用不是動態變化的,它總是指向正確的物件。
改變物件原型的方法
在ES6之前我們要改變物件的原型很麻煩,現在ES6有了setPrototypeOf(),可以輕而易舉的改變物件的原型。
let person = {
getGreeting(){
return 'Hello';
}
};
let dog = {
getGreeting(){
return 'Woof';
}
};
let friend = Object.create(person);
console.log(friend.getGreeting()); // Hello
console.log(Object,getPrototypeOf(friend) === person); //true
Object.setPrototype(friend,dog);
console.log(friend.getGreeting()); // Woof
console.log(Object,getPrototypeOf(friend) === dog); //true
複製程式碼
以上便是ES6有關物件的內容,如果您有不同的見解或者是本文哪裡有錯誤,你都可以在下面留言給我!!!