PJCHENder 未整理筆記

[JS] JavaScript 代理(Proxy)

2019-03-11

[JS] JavaScript 代理(Proxy)

@(JavaScript)[js]

透過 Proxy 可以為物件設立其 gettersetter

Proxy @ MDN
JavaScript Proxy @ DWB

1
2
3
4
5
6
7
8
9
10
11
// var p = new Proxy(target, handler);

// 執行完 proxy 後原本的 targetObj 也會一併改變
const proxy = new Proxy(targetObj, {
get: (obj, prop) => {
return obj[prop];
},
set: (obj, prop, value) => {
obj[prop] = value;
},
})

:exclamation: 注意:proxy 並不是把 targetObj 複製一份,而是參照到同一個物件上,因此對 proxy 做的操作會影響到原本的 targetObj。

設定預設值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const withDefaultValue = (target, defaultValue) => new Proxy(target, {
get: (obj, prop) => (prop in obj) ? obj[prop] : defaultValue
})

let coordination = {
x: 4,
y: 19
};

console.log(coordination.x, coordination.y, coordination.z) // 4, 19, undefined


// set default value with 0
coordination = withDefaultValue(coordination, 0)
console.log(coordination.x, coordination.y, coordination.z) // 4, 19, 0

作為資料驗證(Validation)

Proxy 可以用來驗證某一 Object 設定的屬性和值是否合法:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 把 volume 的值限制在 0 ~ 1 之間
const proxy = new Proxy({}, {
set: (obj, prop, value) => {
if (prop === 'volume') {
if (value > 1) {
value = 1;
} else if (value < 0) {
value = 0;
}
}
obj[prop] = value;
}
})

作為資料格式化(formatting)

Proxy 可以把送進物件的屬性都先進行格式化的動作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const form = new Proxy({}, {
set: (obj, prop, value) => {
if (prop === 'content') {
obj[prop] = {
...value,
isEditing: false,
hasSubmitted: false,
}
}
}
})

form.content = {
label: 'Age',
defaultValue: 20,
}

console.log(form.content)

// {
// label: 'Age',
// defaultValue: 20,
// isEditing: false,
// hasSubmitted: false
// }

掃描二維條碼,分享此文章