es5和es6類的比較

詭異的光發表於2018-11-06

function Person(name) {
    this.name = name; 
}

Person.prototype.sayHello = function(){
    return 'Hi, I am ' + this.name;
}

/*這是es5中 主流建立物件的方法之一,方法寫在原型鏈中*/ 複製程式碼


而用ES6的寫法重寫一下,檢測型別發現Person本質上仍然是函式:

class Person {
    //先建立建構函式
    constructor(name){
        this.name = name;
    }
    sayHello(){
        return 'Hi, I am ' + this.name;
    } 
}複製程式碼


typeof Person; //'function'複製程式碼

呼叫的方式都是一致的:

var me = new Person('Jason');    複製程式碼

用ES6定義class中的方法,定義在原型物件上的。與ES5不同的是,這些定義在原型物件的方法是不可列舉的。

ES6類和模組是嚴格模式下的;

不存在變數提升,保證子類父類的順序;

類的繼承也有新的寫法:

class Female extends Person {
    constructor(name){
        super(name); //呼叫父類的,呼叫之後,子類才有this
        this.gender = 'female';
    }
    sayHello(){
        return super.sayHello() + ', I am ' + this.gender; 
    }
}複製程式碼

注意點,子類必須在父類的建構函式中呼叫super(),這樣才有this物件,因為this物件是從父類繼承下來的。而要在子類中呼叫父類的方法,用super關鍵詞可指代父類。 ES5中類繼承的關係是相反的,先有子類的this,然後用父類的方法應用在this上。 ES6類繼承子類的this是從父類繼承下來的這個特性,使得在ES6中可以構造原生資料結構的子類,這是ES5無法做到的。 ES6也可以定義類的靜態方法和靜態屬性,靜態的意思是這些不會被例項繼承,不需要例項化類,就可以直接拿來用。ES6中class內部只能定義方法,不能定義屬性。在方法名前加上static就表示這個方式是靜態方法,而屬性還是按照ES5的方式來實現。 

// ES5寫法 
Person.total = 0; //靜態屬性
Person.counter = function(){  //靜態方法
    return this.total ++ ;
}

// ES6寫法
class Person {
    ...
    static counter(){
        return this.total ++ ;
    }
}
Person.total = 0;複製程式碼

ES6中當函式用new關鍵詞的時候,增加了new.target屬性來判斷當前呼叫的建構函式。這個有什麼用處呢?可以限制函式的呼叫,比如一定要用new命令來呼叫,或者不能直接被例項化需要呼叫它的子類。

function Person(name){
    if(new.target === Person){
        this.name = name;
    }
    else{
        throw new Error('必須用new生成例項');
    }
}複製程式碼

總結:

  • ES6中的物件的方法不需要單獨寫在原型鏈中
  • ES6中多了靜態方法的宣告與使用,靜態方法是例項物件無法呼叫的,是通過原型.方法名進行呼叫,靜態方法 多數用於儲存 公共方法,比如說要給 這一批 同類物件 進行排序等
  • 類的繼承中繼承關係是相反的(es6:先有父類,再有子類,es5則反之),寫法也不一樣
  • ES6類和模組是嚴格模式下的,不存在變數提升,保證子類父類的順序


相關文章