學習es6 setter/getter研究


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時,就可以正常讀寫屬性
* */

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM