ES6語法(三) 對象

首先,在JavaScript中對象是個很重要的概念,由於在JavaScript中一切都是對象,不管是函數,仍是數組。一樣,ES6此次也帶來了一些新特性。可以幫助咱們更加輕鬆與準確的完成想要完成的目標。數組

對象字面量語法拓展

對象字面量屬性簡寫

在ES6以前。咱們使用字面量建立屬性,會寫一個屬性名,後面跟一個":",最後跟着屬性值。看起來一切都是很簡潔的,可是在屬性值與屬性名同名時,這就很痛苦了,每次都要寫兩個一樣的文字。咱們看個例子:bash

let Person = function(name,age){
        return {
            name : name,
            age : age,
        }
    }
複製代碼

一個兩個這種代碼沒問題,可是當相似的代碼量一旦多起來,那即是很痛苦的一件事了。可是,在ES5中,這個問題將獲得解決。它爲咱們提供了簡寫方式。函數

let Person = function(name,age){
        return {
            name,
            age,
        }
    }
複製代碼

在使用字面量的時候,咱們只需寫一個變量名就好,剩下的工做由JavaScript引擎幫咱們去作。JavaScript引擎回去可訪問做用域查找同名屬性,找到便會將該變量的值賦值給字面量對象的同名屬性。若是沒找到,這個屬性的值爲undefined。oop

對象字面量的可計算屬性名

在ES6以前,咱們能夠在對象建立以後,使用可計算屬性名,可是沒法在對象字面量中使用可計算屬性名。如今ES6將可計算屬性名帶到了對象字面量中。ui

// 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
    
複製代碼

對象方法的簡寫

這不是一個重大的改進。可是能幫助咱們書寫起來更容易。this

// ES6以前按
    let person= {
        getName:function(){
            return : this.name
        }
    }
    
    // ES6
    let person = {
        getName(){
            return this.name;
        }
    }
    
複製代碼

重複的對象字面量屬性

在ES5及以前,咱們若是在對象字面量中聲明瞭兩個同名屬性,嚴格模式下便會報錯。而ES6中將這個特性改變了,不管是否在嚴格模式下,對象字面量中聲明瞭兩個同名屬性,以後後面的屬性會生效。spa

let person = {
        getName(){
            return 'tom';
        },
        
        getName(){
            return 'jure';
        }
    }
    
    person.getName();       // jure
複製代碼

對象自有屬性的枚舉順序

在ES6以前自由屬性的枚舉順序基本都是百家爭鳴,不一樣的JavaScript引擎,都會有不一樣的枚舉順序,此次ES6算是將自由屬性的枚舉順序給出了官方說法prototype

  • 全部數字鍵按照升序排列
  • 全部字符串鍵按照它們被加入對象的順序排列
  • 全部symbol鍵按照它們被加入對象的順序排列

對象新增方法

在ES6也給對象新增了一些方法,下面讓咱們來看看code

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有關對象的內容,若是您有不一樣的看法或者是本文哪裏有錯誤,你均可以在下面留言給我!!!

相關文章
相關標籤/搜索