2013年と2015年の更新 (2011年の元の回答については以下を参照):
これは、仕様書ES2015(別名「ES6」)のように変更:JavaScriptが今持っているプロキシを。プロキシを使用すると、他のオブジェクト(の正面)の真のプロキシであるオブジェクトを作成できます。以下は、文字列であるプロパティ値をすべて取得時にすべて大文字にする簡単な例です。
"use strict";
if (typeof Proxy == "undefined") {
throw new Error("This browser doesn't support Proxy");
}
let original = {
"foo": "bar"
};
let proxy = new Proxy(original, {
get(target, name, receiver) {
let rv = Reflect.get(target, name, receiver);
if (typeof rv === "string") {
rv = rv.toUpperCase();
}
return rv;
}
});
console.log(`original.foo = ${original.foo}`); // "original.foo = bar"
console.log(`proxy.foo = ${proxy.foo}`); // "proxy.foo = BAR"
オーバーライドしない操作には、デフォルトの動作があります。上記ではget
、オーバーライドするのはだけですが、フックできる操作の完全なリストがあります。
でget
ハンドラ関数の引数リスト:
target
プロキシされるオブジェクトです(original
この場合は)。
name
(もちろん)取得するプロパティの名前です。これは通常文字列ですが、シンボルにすることもできます。
receiver
this
プロパティがデータプロパティではなくアクセサである場合に、getter関数で使用されるオブジェクトです。通常の場合には、これは、プロキシまたはそれから継承ものですが、それはできトラップがによってトリガすることができるので、何もしますReflect.get
。
これにより、必要なキャッチオールゲッターおよびセッター機能を備えたオブジェクトを作成できます。
"use strict";
if (typeof Proxy == "undefined") {
throw new Error("This browser doesn't support Proxy");
}
let obj = new Proxy({}, {
get(target, name, receiver) {
if (!Reflect.has(target, name)) {
console.log("Getting non-existent property '" + name + "'");
return undefined;
}
return Reflect.get(target, name, receiver);
},
set(target, name, value, receiver) {
if (!Reflect.has(target, name)) {
console.log(`Setting non-existent property '${name}', initial value: ${value}`);
}
return Reflect.set(target, name, value, receiver);
}
});
console.log(`[before] obj.foo = ${obj.foo}`);
obj.foo = "bar";
console.log(`[after] obj.foo = ${obj.foo}`);
上記の出力は次のとおりです。
存在しないプロパティ 'foo'を取得しています
[前] obj.foo = undefined
存在しないプロパティ 'foo'の設定、初期値:bar
[後] obj.foo = bar
「存在しない」メッセージfoo
がまだ存在しないときに取得しようとしたとき、およびそれを作成したときに取得したが、その後ではないことに注意してください。
2011年からの回答 (2013年および2015年の更新については上記を参照):
いいえ、JavaScriptには包括的なプロパティ機能はありません。使用しているアクセサー構文は仕様のセクション11.1.5でカバーされており、ワイルドカードなどは提供されていません。
あなたは、もちろん、それを行うための機能を実装することができ、私はあなたがおそらく使用したくない推測しているf = obj.prop("foo");
のではなく、f = obj.foo;
とobj.prop("foo", value);
いうよりobj.foo = value;
(機能が未知のプロパティを処理するために必要なことと思われます)。
FWIW、ゲッター関数(セッターロジックを気にしませんでした)は次のようになります。
MyObject.prototype.prop = function(propName) {
if (propName in this) {
// This object or its prototype already has this property,
// return the existing value.
return this[propName];
}
// ...Catch-all, deal with undefined property here...
};
しかし、繰り返しますが、オブジェクトの使用方法がどのように変化するかを考えると、本当にそうしたいとは思いません。