0%

JavaScript 核心 (49) - 物件屬性延伸 - Getter 與 Setter,賦值運算不使用函式

物件賦值

一開始學的物件賦值都是使用直接賦值的方式,然而物件有提供 取值賦值 的功能,可以做出類似物件內函式的操作呦

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

wallet.total = 300;

console.log(wallet.total);

get、set

設定物件 getset 有兩種方法

  • 物件內定義
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var wallet = {
total: 100,
set save(price) {
this.total = this.total + price;
},
get save() {
return this.total / 2;
},
};
console.log(wallet.save); /* 50 */

/* 使用 = 號賦值 */
wallet.save = 300;

console.log(wallet.save); /* 400 */
console.log(wallet);
console.log(Object.getOwnPropertyDescriptor(wallet, 'save'));
/* { enumerable: true, configurable: true, get: ƒ, set: ƒ } */

此時的 save 是可以被列舉、可被刪除的設定
屬性特徵

  • definedProperty 法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var wallet = {
total: 100,
};

Object.defineProperty(wallet, 'save', {
set: function(price) {
this.total = this.total + price;
},
get: function() {
return this.total / 2;
},
});

/* 使用 = 號賦值 */
wallet.save = 300;

console.log(wallet.save); /* 400 */
console.log(wallet);
console.log(Object.getOwnPropertyDescriptor(wallet, 'save'));
/* { enumerable: false, configurable: false, get: ƒ, set: ƒ } */

由於此方法會讓 save 視為原型屬性,所以是不可列舉的、不可被刪除的設定,除非有再額外調整特徵。
屬性特徵

修正後:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var wallet = {
total: 100,
};

Object.defineProperty(wallet, 'save', {
configurable: true,
enumerable: true,
set: function(price) {
this.total = this.total + price;
},
get: function() {
return this.total / 2;
},
});

/* 使用 = 號賦值 */
wallet.save = 300;

console.log(wallet.save); /* 400 */
console.log(wallet);
console.log(Object.getOwnPropertyDescriptor(wallet, 'save'));
/* { enumerable: true, configurable: true, get: ƒ, set: ƒ } */

陣列也適用

由於陣列也是物件的一種,所以也能使用 getset,但只能用 defineProperty 設定哩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var a = [1, 2, 3];
var b = [4, 5, 6];
var c = [7, 8, 9];
Object.defineProperty(a, 'latest', {
get: function() {
return this[this.length - 1];
},
});

console.log(a.latest); /* 3 */
console.log(b.latest); /* undefined */

Object.defineProperty(Array.prototype, 'latest', {
get: function() {
return this[this.length - 1];
},
});

console.log(c.latest); /* 9 */

參考資料

六角學院 - JavaScript 核心篇