7

次のプロキシがあります。

const p = new Proxy({
  [Symbol.iterator]: Array.prototype.values,
  forEach: Array.prototype.forEach,
}, {
  get(target, property) {
    if (property === '0') return 'one';
    if (property === '1') return 'two';
    if (property === 'length') return 2;
    return Reflect.get(target, property);
  },
});

lengthこれは、数値プロパティと要素の量を指定するプロパティを持っているため、配列のようなオブジェクトです。for...ofループを使用して反復できます。

for (const element of p) {
  console.log(element); // logs 'one' and 'two'
}

ただし、このforEach()方法は機能していません。

p.forEach(element => console.log(element));

このコードは何も記録しません。コールバック関数は呼び出されません。なぜ機能しないのですか?どうすれば修正できますか?

コードスニペット:

const p = new Proxy({
  [Symbol.iterator]: Array.prototype.values,
  forEach: Array.prototype.forEach,
}, {
  get(target, property) {
    if (property === '0') return 'one';
    if (property === '1') return 'two';
    if (property === 'length') return 2;
    return Reflect.get(target, property);
  },
});

console.log('for...of loop:');
for (const element of p) {
  console.log(element);
}

console.log('forEach():');
p.forEach(element => console.log(element));
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.16.0/polyfill.min.js"></script>

4

2 に答える 2

7

for...ofループとの違いの 1 つはArray.prototype.forEach()、前者は@@iteratorプロパティを使用してオブジェクトをループするのに対し、後者はプロパティを から まで反復し0lengthオブジェクトにそのプロパティがある場合にのみコールバックを実行することです。[[HasProperty]]内部メソッドを使用します。この場合false、すべての配列要素を返します。

解決策は、呼び出しhas()をインターセプトするハンドラーも追加することです。[[HasProperty]]

作業コード:

const p = new Proxy({
  [Symbol.iterator]: Array.prototype.values,
  forEach: Array.prototype.forEach,
}, {
  get(target, property) {
    if (property === '0') return 'one';
    if (property === '1') return 'two';
    if (property === 'length') return 2;
    return Reflect.get(target, property);
  },
  has(target, property) {
    if (['0', '1', 'length'].includes(property)) return true;
    return Reflect.has(target, property);
  },
});

p.forEach(element => console.log(element));
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.16.0/polyfill.min.js"></script>

于 2016-11-03T18:35:27.400 に答える