學習es6 setter/getter研究
阿新 • • 發佈:2018-03-04
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研究