1. 程式人生 > >學習es6 setter/getter研究

學習es6 setter/getter研究

which 只讀 struct 正常 而不是 原型鏈 技術分享 執行 定義

1.背景

   在ES6中,我們對類的定義如下

 1 class Person {
 2     // 構造函數
 3     constructor (name) {
 4         // 屬性初始化
 5         this.name = name;
 6     }
 7 
 8     // 成員方法
 9     sayName () {
10         console.log(this.name);
11     }
12     
13     // 靜態方法
14     static sayHi () {
15         console.log("Hi~");
16     }
17 }

  其實本質還是基於javascript原型鏈機制開發的語法糖

2. 深入setter/getter

2.1 setter/getter的調用執行時機

 1 class Person {
 2     constructor(name,age) {
 3         this.name = name;
 4         this.age = age;
 5     }
 6                 
 7     set name(name) {
 8         console.log("setter");
 9         this.name = name;
10 } 11 12 get name() { 13 console.log("getter"); 14 return this.name; 15 } 16 }

發現上面的代碼報錯

技術分享圖片

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

我們稍作修改,讓這個代碼可以正常執行,達到我們想要的效果。

 1 // 針對上面的情況,稍作修改
 2 class Person {
 3     constructor(name,age) {
 4         this.name = name;// 執行這裏 --- 1
 5         this.age = age;
 6     }
 7                 
 8     set name(name) { // 進入到這裏進行設置  -- 2
 9         console.log("setter");
10         this._name = name;
11     }
12                 
13     get name() { // 在這裏將對應的值返回 --- 3
14         console.log("getter");
15         return this._name;
16     }
17                 
18     sayName() { // 這裏的調用,又從 1-2-3
19         console.log(this.name);
20     }
21 }
22 let p2 = new Person("lisi",22);
23 console.log(p2);// 真實的屬性是 age  _name   而不是name
24 p2.sayName();
25 console.log(p2._name);// 如果你訪問的是 p2.name  最後會執行 1-3 這兩個步驟,會打印出getter    

控制臺結果如下:

技術分享圖片

/**
* 總結
*    只要this.+屬性名 和get 屬性名/ set 屬性名 中,屬性名一致,
*    this.name 會去調用getter 和 setter ,也就是說 getter和setter是hock函數
*    而真實存儲的屬性是 _name 我們可以在實例化後,直接獲取
* */

2.2 只有getter定義只讀屬性

 1 // 只有getter定義只讀屬性
 2 class foo {
 3     constructor(name) {
 4         this.name = name;
 5     }
 6                  
 7     get name() {
 8         console.log(`getter函數`);
 9         return this.name;
10     }
11 }
12 //Cannot set property name of #<foo> which has only a getter
13  let p3 = new foo("李四");

/**
* 總結:
*   當一個屬性只有getter沒有setter的時候,我們是無法進行賦值操作的(第一次初始化也不行),這一點需要註意
*   當沒有getter和setter時,就可以正常讀寫屬性
* */

學習es6 setter/getter研究