handler.has() 方法主要用于拦截 HasProperty 操作,即判断对象是否具有某个属性时,这个方法会生效,典型的操作就是 in 运算符。
const proxy = new Proxy(target, {has: function (target, property) {// do something},});
| 参数 | 说明 | 类型 |
|---|---|---|
target | 目标对象 | object |
property | 需要检查是否存在的属性 | string |
该方法会拦截目标对象的以下操作:
foo in proxyfoo in Object.create(proxy)with 检查:with(proxy){(foo);}Reflect.has()如果违背了以下的约束,proxy 会抛出 TypeError 异常:
以下代码演示如何拦截 in 操作符:
const proxy = new Proxy({},{has: function (target, prop) {console.log('Called:' + prop);return true;},});console.log('foo' in proxy);// "Called: foo"// true
下面代码违反了约束:
const foo = { a: 10 };Object.preventExtensions(foo);const proxy = new Proxy(foo, {has: function (target, prop) {return false;},});console.log('a' in proxy);// Uncaught TypeError: 'has' on proxy: trap returned falsish for property 'a' but the proxy target is not extensible
const handler = {has(target, prop) {if (key[0] === '_') {return false;}return key in target;},};const target = { _prop: 'foo', prop: 'foo' };const proxy = new Proxy(target, handler);console.log('_prop' in proxy);// false
上面代码中,如果原对象的属性名的第一个字符是下划线,proxy.has 就会返回 false,从而不会被 in 运算符发现。
值得注意的是,has 方法拦截的是 HasProperty 操作,而不是 HasOwnProperty 操作,即 has 方法不判断一个属性是对象自身的属性,还是继承的属性。
另外,虽然 for...in 循环也用到了 in 运算符,但是 has 拦截对 for...in 循环不生效。