前言
如何利用 Getter 與 Setter 來進行物件屬性的賦值
var wallet = {
total: 100
};
假設錢包裡面的總金額有 100 元,我們要修改裡面的錢,通常會使用
wallet.total = 300;
console.log(wallet.total);
印出來後
這樣子的作法,我們是直接把值覆蓋過原本的值,但有時候我們會需要根據原本的值進行一些運算,
這種狀況就非常適合使用 Getter 與 Setter
- Getter: 取得特定值的方法
- Setter: 存特定值的方法
以上面的例子為基礎,用 Setter 設定存 total 的屬性
Setter 存特定值的方法
var wallet = {
total: 100,
set save (price) {
this.total += price / 2;
}
};
wallet.save = 300;
console.log(wallet.total);
我們先在 wallet 的屬性中新增了下面這段
set save (price) {
this.total += price / 2;
}
可以看到利用 set 作為字首,接上自定義名稱 save ,再加上( ) { },有點類似傳統函式,但少了 function 的開頭宣
告,之後也是將要進行運算的程式撰寫在大括號 { } 內,就算定義完成。
實際上的呼叫和傳統函式的呼叫不太一樣,是透過
wallet.save = 300;
這樣的方式,如果有參數的話,則利用 = 要帶入的參數傳入,所以這邊的寫法如上面所示,
而結果就可以看到是運算過後的250
Getter 取得特定值的方法
其實 Getter 跟 Setter 差不多,只是差別在於最後要 return 你取到的值,並且不會有傳入的參數。
var wallet = {
total: 100,
set save (price) {
this.total += price / 2;
},
get save () {
return this.total;
}
};
一樣的方式 ~ 用逗號 , 隔開之後,使用關鍵字 get 加上自定義名稱 save ,再加上 ( ) { }
那麼執行的話,只需要使用表達式即可,wallet.save
var wallet = {
total: 100,
set save (price) {
this.total += price / 2;
},
get save () {
return this.total;
}
};
wallet.save = 300;
console.log(wallet.total);
console.log(wallet.save);
接著來看看 wallet 這個物件變成怎麼樣
可以看到 total、getter、setter還有一個 save: (...) 這個是 getter,但還沒有取值的狀態,如果我們點下去之後,才會從點下去的當下去資料中取這個值
稍微把程式碼改動一下讓大家比較能夠了解
var wallet = {
total: 100,
set save (price) {
this.total += price / 2;
},
get save () {
return this.total;
}
};
console.log(wallet.save, wallet);
wallet.save = 300;
// console.log(wallet.total);
// console.log(wallet.save);
可以看到我故意把 console.log(wallet.save, wallet); 放在 setter 執行之前,這樣取到的值一定是 100 ,
但是這時候物件裡面的 save: (...) 我還沒按,按了之後就呈現
也就是說,按下去的當下,js 的程式碼都全部跑完了,才去取得處理完的資料狀態,也就是 250
利用 Object.defineProperty( ) 定義 Getter 以及 Setter
var wallet = {
total: 100
};
Object.defineProperty(wallet, 'save', {
set: function (price) {
this.total += price / 2;
},
get: function () {
return this.total;
}
});
console.log(wallet.save, wallet);
wallet.save = 300;
如同之前的寫法所示,功能一樣可以照常運作,只是眼尖的人可能會發現 save: (...) 的屬性顏色跟之前的不一樣,變成淡紫
色,如果還對上一篇文章有印象的人就會知道,這代表 enumerable 的狀態是 false
所以我們就來看看 Getter 以及 Setter 現在的狀態:
console.log('Getter and Setter', Object.getOwnPropertyDescriptor(wallet, 'save'));
果然,configurable 以及 enumerable 都是 false 。
那麼如果我們今天要把它改成 true 的話也很簡單,只需要 Object.defineProperty 中進行調整就可以了
Object.defineProperty(wallet, 'save', {
configurable:true,
enumerable: true,
set: function (price) {
this.total += price / 2;
},
get: function () {
return this.total;
}
});
console.log('Getter and Setter', Object.getOwnPropertyDescriptor(wallet, 'save'));
實戰練習
Q: 需要取得陣列中的第一個值以及最後一個值
A:
var a = ['1', '2', '3'];
Object.defineProperties(Array.prototype, {
getFirst: {
get: function () {
return this[0];
}
},
getLast: {
get: function () {
return this[this.length - 1];
}
}
});
console.log('getFirst', a.getFirst);
console.log('getLast', a.getLast);