我需要练习一些数据映射函数的代码.为此,我需要一个代理,当请求任何属性时,它返回一个具有一个元素(本身;一个可迭代数组)的可迭代array.这将激活数据映射器层(此处未显示)中的所有循环和属性判断.

大概是这样的:

p = new Proxy([], {
  get(obj, prop) {
    if(prop === 'length') return obj.length
    if(prop === 'push') return obj.push
    if(p.length === 0) p.push(p)
    return p
  }}
)

这是一个良好的开端:

> p.any.length
1

但在这里失败了:

> for(let v of p.any){console.log(v)}
Uncaught TypeError: p.any is not iterable

我需要循环来迭代和sole.log一个元素:

> p.any
Proxy [
  <ref *1> [ Proxy [ [Circular *1], [Object] ] ],
  { get: [Function: get] }
]

一些代理docsguides覆盖in和对象,但不覆盖of和array.

推荐答案

出现该错误的原因是,for..of循环将查询具有@@iterator符号属性的代理对象,而您的代码将返回p,而不是像Array.prototype[Symbol.iterator]那样返回iterator.

解决方案很简单:就像您允许访问lengthpush一样,也可以对符号属性执行相同的操作.

你可能会考虑的另一件事是,不要做p.push(p),而是做obj.push(p).这样,您可以忽略用户发出的push,并可以将此操作作为first操作来执行.

结果代码:

const p = new Proxy([], {
  get(obj, prop) {
    if (obj.length === 0) obj.push(p);
    if (prop === 'length' || typeof prop === "symbol") return obj[prop];
    return p;
  }}
);

for (let v of p) {
  console.log(v);
}

console.log(p);
console.log(p.any);
console.log(p.any.any);

也许您还应该让其他属性访问通过,比如数组方法(forEachreducemapfilter,...等).

Javascript相关问答推荐

nPM审计始终发现0个漏洞

Next.js Next/Image图像隐含性有任何类型-如何修复?

如何为GrapesJS模板编辑器创建自定义撤销/重复按钮?

我在这个黑暗模式按钮上做错了什么?

如何找出摆线表面上y与x相交的地方?

Snowflake JavaScript存储过程返回成功,尽管预期失败

给定一个凸多边形作为一组边,如何根据到最近边的距离填充里面的区域

当点击注册页面上的注册按钮时,邮箱重复

空的结果抓取网站与Fetch和Cheerio

查找最长的子序列-无法重置数组

Regex结果包含额外的match/group,只带一个返回

在JS中拖放:检测文件

如何在每次单击按钮时重新加载HighChart/设置HighChart动画?

如何迭代叔父元素的子HTML元素

用JS从平面文件构建树形 struct 的JSON

如何使用JS创建一个明暗功能按钮?

删除加载页面时不存在的元素(JavaScript)

当从其他文件创建类实例时,为什么工作线程不工作?

react 路由如何使用从加载器返回的数据

如何在TransformControls模式下只保留箭头进行翻译?