使用 has 陷阱函数隐藏属性
in 运算符用于判断指定对象中是否存在某个属性,如果对象的属性名与指定的字符串或符号值相匹配,那么 in 运算符应当返回 true,无论该属性是对象自身的属性还是其原型的属性。例如:
let target = {
value: 42;
}
console.log("value" in target); // true
console.log("toString" in target); // true
value 与 toString 均存在于 object 对象中,因此 in 运算符都会返回 true。其中 value 是对象自身的属性,而 toString 则是原型属性(从 Object 对象上继承而来)。代理允许你使用 has 陷阱函数来拦截这个操作,从而在使用 in 运算符时返回不同的结果。
has 陷阱函数会在使用 in 运算符的情况下被调用,并且会被传入两个参数:
-
trapTarget:需要读取属性的对象(即代理的目标对象);
-
key:需要检查的属性的键(字符串类型或符号类型) 。
Reflect.has() 方法接受与之相同的参数,并向 in 运算符返回默认响应结果。使用 has 陷阱函数以及 Reflect.has() 方法,允许你修改部分属性在接受 in 检测时的行为,但保留其他属性的默认行为。例如,假设你只想要隐藏 value 属性,你可以这么做:
let target = {
name: "target",
value: 42
};
let proxy = new Proxy(target, {
has(trapTarget, key) {
if (key === "value") {
return false;
} else {
return Reflect.has(trapTarget, key);
}
}
});
console.log("value" in proxy); // false
console.log("name" in proxy); // true
console.log("toString" in proxy); // true
这里的 proxy 对象使用了 has 陷阱函数,用于检查 key 值是否为 "value"。 如果是,则返回 false;否则通过调用 Reflect.has() 方法来返回默认的结果。这样,虽然 value 属性确实存在于目标对象中,但 in 运算符却会对该属性返回 false;而其他的属性(name 与 toString)则会正确地返回 true。