getter & setter

getter & setter

getter 和 setter算是我比較不熟悉的物件屬性,在這邊跟大家分享一下上課筆記。希望我以後也能熟練地運用。

定義和使用

1
2
3
4
5
6
7
8
var wallet = {
total:100
}

//改寫total
wallet.total = 60;

console.log(wallet.total) //60

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;
}
}
//等號右邊為要傳入setter save的參數,他並不會覆蓋掉save
wallet.save = 500;
console.log(wallet.total); //350

注意,要使用等號將參數傳入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); //50

注意調用的方法為物件屬性的調用方式

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); //50

注意點

在使用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
}
}

//印出getter和wallet
console.log(wallet.save, wallet);
//結果: 50, wallet物件

//setter
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) //3

var b = [3, 4, 15];
console.log(b.last) //15
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×