javascript - Array.prototype.forEach() 在使用 get 处理程序的代理上调用时不起作用

标签 javascript foreach ecmascript-6 iteration es6-proxy

我有以下代理:

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>

最佳答案

for...of 循环和 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>

关于javascript - Array.prototype.forEach() 在使用 get 处理程序的代理上调用时不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40408917/

相关文章:

php foreach循环重复项

javascript - 如何格式化具有空行的 excel 文件以具有嵌套数组并匹配我需要呈现的 JSON 对象?

javascript - 悬停时跟随指针的 Div

javascript - 从单行中的嵌套 JSON 对象获取数据

javascript - 如何生成静态 Django JavaScript 翻译目录

ios - 有没有办法遍历字典?

javascript - CORS 不适用于 firebase 云功能中的特定域

PHP循环curl请求一个一个

javascript - 通过将嵌套属性提升到一个级别来转换 javascript 对象

javascript - 在 ES6 的 child 的 super 方法中获取 js 类名