[學習es6]setter/getter探究

1. 背景

在es6中,咱們能夠用class關鍵字來定義類,語法以下javascript

class Person {
    // 構造函數
    constructor (name) {
        // 屬性初始化
        this.name = name;
    }

    // 成員方法
    sayName () {
        console.log(this.name);
    }
    
    // 靜態方法
    static sayHi () {
        console.log("Hi~");
    }
}

其實本質仍是基於javascript原型鏈機制開發的語法糖,其中,本人對setter/getter進行一番研究,發現了很多坑。java

2. 深刻setter/getter

2.1 setter/getter的調用執行時機

class Person {
    constructor (name, age) {
        this.name = name;
        this.age = age;
    }
    set name (name) {
        console.log("setter");
        this.name = name;
    }
    get name () {
        console.log("getter");
        return this.name;
    }
}

var p = new Person("zhang", 25);

很快,咱們就會發現代碼報錯了es6

setter-getter.png

這是由於,在構造函數中執行this.name=name的時候,就會去調用set name,在set name方法中,咱們又執行this.name = name,進行無限遞歸,最後致使棧溢出(RangeError)。函數

咱們稍做修改,讓這個代碼能夠正常執行,達到咱們想要的效果。this

class Person {
    constructor (name, age) {
        this.name = name;
        this.age = age;
    }
    set name (name) {
        console.log("setter");
        this._name = name;
    }
    get name () {
        console.log("getter");
        return this._name;
    }

    // 加一個成員方法
    sayName () {
        console.log(this.name);
    }
}

var p = new Person("zhang", 25); 
p.sayName();

執行結果爲spa

圖片描述

到這裏就能夠明白了,原來只要this.name中的屬性名和set name/get name後面的name一致,對this.name就會調用setter/getter,也就是說setter/getter是hook函數,而真實的存儲變量是_name,咱們能夠在代碼中直接獲取它。code

class Person {
    constructor (name, age) {
        this.name = name;
        this.age = age;
    }
    set name (name) {
        console.log("setter");
        this._name = name;
    }
    get name () {
        console.log("getter");
        return this._name;
    }

    // 加一個成員方法
    sayName () {
        console.log(this.name);
    }
}

var p = new Person("zhang", 25); 
console.log(p._name); // "zhang"

執行結果爲blog

圖片描述

注意到結果並無執行getter,由於咱們直接訪問了p._name,而不是p.name遞歸

2.2 只有getter定義只讀屬性

當一個屬性只有getter沒有setter的時候,咱們是沒法進行賦值操做的(第一次初始化也不行),這一點也是至關地。例如圖片

class Person {
    constructor (name) {
        this.name = name;
    }
    // 只有getter
    get name () {
        console.log("getter");
        return this.name;
    }
}

var p = new Person("zhang");

執行結果爲

圖片描述

當沒有getter和setter時,就能夠正常讀寫屬性

相關文章
相關標籤/搜索