Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中类似getter的自定义数组_Javascript_Ecmascript 6_Es6 Class_Es6 Proxy - Fatal编程技术网

JavaScript中类似getter的自定义数组

JavaScript中类似getter的自定义数组,javascript,ecmascript-6,es6-class,es6-proxy,Javascript,Ecmascript 6,Es6 Class,Es6 Proxy,我有一个简单的ES6课程,如下所示: class Ring extends Array { insert (item, index) { this.splice(index, 0, item); return this; } } 我想使环形对象的索引换行,以便new-Ring(1,2,3)[3]返回1,new-Ring(1,2,3)[-1]返回3,依此类推。这在ES6中可能吗?如果是,我将如何实施 我读过关于代理的书,它允许完全定制的getter

我有一个简单的ES6课程,如下所示:

class Ring extends Array {
    insert (item, index) {
        this.splice(index, 0, item);
        return this;
    }
}
我想使环形对象的索引换行,以便
new-Ring(1,2,3)[3]
返回1,
new-Ring(1,2,3)[-1]
返回3,依此类推。这在ES6中可能吗?如果是,我将如何实施

我读过关于代理的书,它允许完全定制的getter,但我不知道如何将代理应用于类。我确实做到了:

var myRing = new Proxy (Ring.prototype, {
    get: function (target, name) {
        var len = target.length;
        if (/^-?\d+$/.test(name))
            return target[(name % len + len) % len];
        return target[name];
    }
});

myRing
现在是一个支持环绕索引的环形对象。问题是我每次都必须定义这样的环形对象。是否有方法将此代理应用于类,以便调用
new Ring()
返回它?

警告:这是一个丑陋的黑客行为

仔细想想,这是一个相当简单的方法

function ClassToProxy(_class, handler) {
    return (...args) => new Proxy(new _class(...args), handler);
}
这定义了一个函数
ClassToProxy
。第一个参数是要添加行为的类,第二个参数是处理程序


下面是使用示例:

const Ring = ClassToProxy(

    // Class
    class Ring {
        constructor(...items) {
            this.items = items;
        }
    },

    // Handler
    {
        get: function(target, name) {
            return target.items[name];
        }
    }
)
基本上是这样

class ProxyRing extends Array {
  constructor(...args) {
    super(...args)

    return new Proxy(this, {
      get: function (target, name) {
          var len = target.length;
          if (typeof name === 'string' && /^-?\d+$/.test(name))
              return target[(name % len + len) % len];
          return target[name];
      }
    });
  }

  insert (item, index) {
      this.splice(index, 0, item);
      return this;
  }
}

您基本上有两种选择:

  • 在每个实例周围环绕一个
    代理

    const handler = {
        get(target, name) {
            var len = target.length;
            if (typeof name === 'string' && /^-?\d+$/.test(name))
                return target[(name % len + len) % len];
            return target[name];
        }
    };
    class Ring extends Array {
        constructor() {
            super()
            return new Proxy(this, handler);
        }
        …
    }
    
  • 围绕类的原型包装一个
    代理

    class Ring extends Array {
        constructor() {
            super()
        }
        …
    }
    Ring.prototype = new Proxy(Ring.prototype, {
        get(target, name, receiver) {
            var len = target.length;
            if (typeof name === 'string' && /^-?\d+$/.test(name)) {
                if (+name < 0)
                    return receiver[(name % len) + len];
                if (+name > len-1)
                    return receiver[name % len];
            }
            return target[name];
        }
    });
    
    类环扩展数组{
    构造函数(){
    超级()
    }
    …
    }
    Ring.prototype=新代理(Ring.prototype{
    获取(目标、名称、接收者){
    var len=target.length;
    if(typeof name==='string'&&/^-?\d+$/.test(name)){
    如果(+名称<0)
    返回接收方[(名称%len)+len];
    如果(+name>len-1)
    返回接收方[名称%len];
    }
    返回目标[名称];
    }
    });
    

只需使用构造函数包装
newproxy(…)
,并使用
new
调用它即可。是的,没有代理你不能这么做。嗯。。。这非常接近,只是它不支持
new
。。。这似乎是完美的工作!我没有意识到构造函数可以显式返回值…嗯。。。哇,我从来不知道你可以从ES6类的构造函数中返回一个值……是的。在大多数情况下,这是不合理的,但事实正是如此。第二种方法似乎对我不起作用。我尝试仅使用代理部分来扩展Number类,并通过将
Number.prototype
的两个实例都更改为
Number.prototype.\uuuuuuuuu
@ETHproductions.我不确定为什么要将
Number.prototype
设置为代理来实现这一点?您可能应该更改
。\uuuu proto\uuuu
,因为这会在原型链中引入另一个对象。