handler.has()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2016年9月.
handler.has() は、オブジェクトの [[HasProperty]] 内部メソッドに対するトラップです。in 演算子などの操作で使用されます。
試してみましょう
const handler = {
has(target, key) {
if (key[0] === "_") {
return false;
}
return key in target;
},
};
const monster = {
_secret: "easily scared",
eyeCount: 4,
};
const proxy = new Proxy(monster, handler);
console.log("eyeCount" in proxy);
// 予想される結果: true
console.log("_secret" in proxy);
// 予想される結果: false
console.log("_secret" in monster);
// 予想される結果: true
構文
js
new Proxy(target, {
has(target, property) {
}
})
引数
次の引数は has() メソッドに渡されます。 this はハンドラーにバインドされます。
返値
has() メソッドは、プロパティが存在するかどうかの論理値 (Boolean) を返す必要があります。それ以外の値は論理値に変換されます。
解説
>介入
このトラップは下記の操作に介入できます。
in演算子:foo in proxywithチェック:with(proxy) { (foo); }Reflect.has()
他にも、[[HasProperty]] 内部メソッドを呼び出すあらゆる操作に介入できます。
不変条件
プロキシーの [[HasProperty]] 内部メソッドは、ハンドラー定義が次の不変条件のいずれかに違反する場合、 TypeError が発生します。
- プロパティが対象とするオブジェクトの構成不可な自己プロパティとして存在する場合、そのプロパティを存在しないとして報告することはできません。つまり、
Reflect.getOwnPropertyDescriptor()がtargetのプロパティに対してconfigurable: falseを返す場合、トラップはtrueを返す必要があります。 - プロパティは、対象とするオブジェクトの自分自身でプロパティとして存在し、かつ対象とするオブジェクトが拡張可能でない場合、存在しないとして報告できません。つまり、
Reflect.isExtensible()がtargetでfalseを返す場合、かつReflect.getOwnPropertyDescriptor()がtargetのプロパティのプロパティ記述子を返す場合、トラップはtrueを返さなければなりません。
例
>in 演算子のトラップ
次のコードでは in 演算子をトラップします。
js
const p = new Proxy(
{},
{
has(target, prop) {
console.log(`called: ${prop}`);
return true;
},
},
);
console.log("a" in p);
// "called: a"
// true
次のコードでは不変条件に違反します。
js
const obj = { a: 10 };
Object.preventExtensions(obj);
const p = new Proxy(obj, {
has(target, prop) {
return false;
},
});
"a" in p; // TypeError is thrown
仕様書
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p> |