Proxy オブジェクトでプロパティ列挙 (for...in) を制御するにはどうすればよいでしょうか? 質問する

Proxy オブジェクトでプロパティ列挙 (for...in) を制御するにはどうすればよいでしょうか? 質問する

オブジェクトをラップしていますプロキシそしてそれを反復します。反復するキーを制御するにはどうすればよいでしょうか?

キーを上書きしない場合、プロキシは機能します。

var obj = {"hello": "world"}
var proxy = new Proxy(obj, {})
for (var key in proxy){
    console.log(key)
}
// logs "Hello"

ただし、ハンドラー内のキーを変更しても何もログに記録されませんownKeys

var obj = {"hello": "world"}
var proxy = new Proxy(obj, {
    ownKeys: function(){
        return ["a", "b"]
    }
})
for (var key in proxy){
    console.log(key)
}
// Logs nothing

"hello"一部として戻った場合のみownKeysログ"hello"に記録されます。

どうやら、enumerateES6 ではトラップされていましたが、ES7 では削除されました。

for...inプロキシを使用してループを制御することはまだ可能ですか?enumerate仕様から削除されたのはなぜですか?

ベストアンサー1

残念ながら、これはもう実行できません。

Brian Terlson (EcmaScript 仕様の編集者) は次のように書いています:

プロキシ列挙トラップと for-in の問題。反復子が観測可能な影響を引き起こすため、実装はオブジェクト内のキーのリストを事前に設定できません。つまり、反復子は反復ごとにプルされる必要があります。前回の会議では、列挙トラップが反復子を使い果たしても問題はないと考え、それで解決すると考えました。問題は、主に削除が原因で、オブジェクトとそのオブジェクトのプロキシの間に観測可能な違いがあることです。

(ソース:https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-01/2016-01-28.md#5xix-proxy-enumerate---revisit-decision-to-exhaust-iterator経由https://ecmascript-daily.github.io/2016/02/10/why-remove-enumerate-and-reflect-enumerate

そのため、満足のいく方法で解決できなかった技術的な課題のために削除されました。

もっているプロキシトラップ

演算子in自体は、hasプロキシトラップ:

var p = new Proxy({}, {
  has: function(target, prop) {
    if (prop === 'a') { return true; }
    return false;
  }
});
'a' in p; // true
'b' in p; // false

代替

ループは最近ではレガシー機能になっているためfor (let key in proxy)、プロキシ トラップでは次のいずれかを使用できますownKeys

  • Object.keys()(列挙可能なプロパティのみ)
  • Object.getOwnPropertyNames()(所有物件)
  • Reflect.ownKeys()(独自のプロパティとシンボル)

ここに画像の説明を入力してください(ソース:https://twitter.com/nilssolanki/status/659839340592422912

(ただし、プロキシを使っているのであれば、おそらくすでにご存知でしょう)

おすすめ記事