constproxy=newProxy({}, {set(obj, property, value) {if (property ==='age') {if (!Number.isInteger(value)) {thrownewTypeError('The age is not an integer'); }if (value >150|| value <0) {thrownewRangeError('Wooo. Are you kinding me?'); } } elseif (property.startsWith('_')) {thrownewError('Can not write property which start with "_"') }// 对于满足条件的 age 属性以及其他属性,直接保存 obj[prop] = value;returntrue; }});proxy.age; // undefinedproxy.age =24;proxy.age; // 24proxy.age ='24'// TypeError: The age is not an integerproxy.age =-1// RangeError: Wooo. Are you kinding me?proxy._sex ='male'; // Error: Can not write property which start with "_"
可以通过设置代理对象的set处理器轻松的根据需求对对象的写入进行控制。
deleteProperty(target, property)
在删除代理对象的某个属性时触发该操作,比如在执行 delete proxy.foo时。
constproxy=newProxy({ _a:1, a:2,}, {deleteProperty(target, property) {if (property.startsWith('_')) {throwError('Can not delete property which start with "_"') }returndelete target[property]; }});deleteproxy.a;proxy.a; // undefineddeleteproxy._a; // Error: Can not delete property which start with "_"
constobj= {};Object.defineProperty(obj,'a', { configurable:false, enumerable:true, value:10});constp=newProxy(obj, {ownKeys(target) {return ['a',Symbol.for('b'),'c']; }});console.log(Object.getOwnPropertyNames(p)); // [ 'a', 'c' ]constp2=newProxy(obj, {ownKeys(target) {return ['a',123,12.5,true,false,undefined,null, {}, []]; }});console.log(Object.getOwnPropertyNames(p2)); // TypeError: XXX is not a valid property nameconstp3=newProxy(obj, {ownKeys(target) {return ['b','c']; }});console.log(Object.getOwnPropertyNames(p3)); // TypeError: 'ownKeys' on proxy: trap result did not include 'a'Object.preventExtensions(obj);constp4=newProxy(obj, {ownKeys(target) {return ['a','b']; }});console.log(Object.getOwnPropertyNames(p4)); // TypeError: 'ownKeys' on proxy: trap returned extra keys but proxy target is non-extensible
constobj= { a:20 };Object.defineProperty(obj,'b', { configurable:false, enumerable:true, value:20});var p =newProxy(obj, {getOwnPropertyDescriptor(target, prop) {return { configurable:true, enumerable:true, value:10 }; }});console.log(Object.getOwnPropertyDescriptor(p,'a').value);var p2 =newProxy(obj, {getOwnPropertyDescriptor(target, prop) {return []; }});console.log(Object.getOwnPropertyDescriptor(p2,'b'));// TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property 'a' which is either non-existant or configurable in the proxy target
var p3 =newProxy(obj, {getOwnPropertyDescriptor(target, prop) {returnundefined; }});console.log(Object.getOwnPropertyDescriptor(p3,'b'));// TypeError: 'getOwnPropertyDescriptor' on proxy: trap returned undefined for property 'a' which is non-configurable in the proxy target
constproxy=newProxy(function () {}, {setPrototypeOf(target, proto) {returnfalse; }});Object.setPrototypeOf(proxy, {}); // TypeError: 'setPrototypeOf' on proxy: trap returned falsishconsttarget= {};Object.preventExtensions(target);constproxy2=newProxy(target, {setPrototypeOf(target, proto) {returntrue; }});Object.setPrototypeOf(proxy2, {}); // TypeError: 'setPrototypeOf' on proxy: trap returned truish for setting a new prototype on the non-extensible proxy target