handler.set()
方法用于拦截对象属性的赋值操作。
const proxy = new Proxy(target, {get: function (target, property, value, receiver) {// do something},});
参数 | 说明 | 类型 |
---|---|---|
target | 目标对象 | object |
property | 属性名 | string 或 symbol |
value | 新属性值 | any |
receiver | 最初被调用的对象 | object |
set
方法返回一个布尔值,表示是否设置成功。
该方法会拦截目标对象的以下操作:
proxy[foo] = bar
和 proxy.foo = bar
Object.create(proxy)[foo] = bar
Reflect.set()
如果违背了以下的约束,proxy
会抛出 TypeError 异常:
set
代理不会生效,且不能改变它的值[[Set]]
属性的是 undefined
,则不能设置它的值set
方法返回 false
,那么也会抛出一个 TypeError 异常const proxy = new Proxy({},{set: function (target, prop, value, receiver) {target[prop] = value;console.log('property set:' + prop + ' = ' + value);return true;},});console.log('foo' in proxy);// falseproxy.foo = 100;// 'property set:' foo = 100console.log('foo' in proxy);// trueconsole.log(proxy.foo);// 100
假设 Person
对象有一个 age
属性,该属性应该是一个不大于 200 的整数,那么可以使用 Proxy
保证 age
的属性值符合要求。
const validator = {set: function (target, prop, value) {if (prop === 'age') {if (!Number.isInteger(value)) {throw new TypeError('The age is not an integer');}if (value > 200) {throw new RangeError('The age seems invalid');}}// 对于满足条件的 age 属性以及其他属性,直接保存target[prop] = value;},};let person = new Proxy({}, validator);person.age = 100;console.log(person.age);// 100person.age = 'YOUNG';// Uncaught TypeError: The age is not an integerperson.age = 300;// Uncaught RangeError: The age seems invalid
下面示例代码,只要读写的属性名第一个字符不是下划线,一律抛错,从而达到禁止读写内部属性的目的。
const invariant = function (key, action) {if (key[0] === '_') {throw new Error(`Invalid attempt to ${action} private "${key}" property`);}};const handler = {get(target, prop) {invariant(prop, 'get');return target[prop];},set(target, prop, value) {invariant(prop, 'set');target[prop] = value;return true;},};const target = {};const proxy = new Proxy(target, handler);console.log(proxy._prop);// Uncaught Error: Invalid attempt to get private "_prop" propertyproxy._prop = 'c';// Uncaught Error: Invalid attempt to set private "_prop" property