getter 和 setter算是我比較不熟悉的物件屬性,在這邊跟大家分享一下上課筆記。希望我以後也能熟練地運用。
定義和使用
1 2 3 4 5 6 7 8
| var wallet = { total:100 }
wallet.total = 60;
console.log(wallet.total)
|
Getter是取得特定值的方法,Setter能讓我們在存值之前先做一些手續。
如何使用setter
setter會設定值
1 2 3 4 5 6 7 8 9
| var wallet = { total:100, set save(price){ this.total = this.total + price/2; } }
wallet.save = 500; console.log(wallet.total);
|
注意,要使用等號將參數傳入setter save函式
如何使用getter
getter會取得值,因此要return
1 2 3 4 5 6 7 8
| var wallet = { total:100, get save(){ return this.total / 2; } }
console.log(wallet.save);
|
注意調用的方法為物件屬性的調用方式
1 2 3 4 5 6 7 8 9 10 11
| var wallet = { total:100, get save(){ return this.total / 2; }, set save(price){ this.total = this.total + price/2 } }
console.log(wallet);
|
注意點
在使用chrome查看時,可以看到save屬性為一個括號,點開後才會有值,事實上在點開時,setter才會執行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var wallet = { total:100, get save(){ return this.total / 2; }, set save(price){ this.total = this.total + price/2 } }
console.log(wallet.save, wallet);
wallet.save = 200;
|
按照程式碼由上往下運作的邏輯,wallet.save = 200(setter)
發生在console.log之後,也就是說,setter應該會在印出結果之後才調整total,因此wallet.save才會印出第一個結果50,然而當我們打開wallet物件中的save屬性,卻發現它變成了100。
為什麼是100?因為我們使用wallet.save = 200
時,把200傳入Setter,按照Setter內的計算方式,total的值會是200/2+100 = 200,而getter的計算方法是將total(此時等於200)除以2,因此是100。
這可以證明,當我們打開chrome內getter的括號後,getter才會開始運算,而這已經發生在wallet.save = 200
這一行之後了。
另一種定義方式
使用defineProperty
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var wallet = { total:500, }; Object.defineProperty(wallet,'save',{ set:function(price){ this.total = this.total + price/2 }, get:function(){ return this.total/2; } }) console.log(wallet); console.log(wallet.save);
|
成功加上getter和setter
但是按照這方式新增的getter,特徵竟為不可列舉?
1
| console.log(Object.getOwnPropertyDescriptor(wallet,'save'))
|
屬性特徵變成不可刪除(configurable)也不可列舉(enumerable)
因此在使用defineProperty時,記得設定這兩個特徵,以免出現不想要的結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var wallet = { total:500, }; Object.defineProperty(wallet,'save',{ configurable:true, enumerable:true, set:function(price){ this.total = this.total + price/2 }, get:function(){ return this.total/2; } }) console.log(wallet); console.log(Object.getOwnPropertyDescriptor(wallet,'save'))
|
實作上的範例
1 2 3 4 5 6 7 8 9 10 11 12 13
| var a = [1, 2, 3];
Object.defineProperty(Array.prototype,'last',{ get:function(){ return this[this.length-1]; } }) console.log(a.last)
var b = [3, 4, 15]; console.log(b.last)
|