admin管理员组文章数量:1290230
I have a simple ES6 class, like so:
class Ring extends Array {
insert (item, index) {
this.splice(index, 0, item);
return this;
}
}
I want to make it so that the indexing for Ring objects wraps, so that new Ring(1, 2, 3)[3]
returns 1, new Ring(1, 2, 3)[-1]
returns 3, and so on. Is this possible in ES6? If so, how would I implement it?
I've read about proxies, which allow a pletely customized getter, but I can't figure out how to apply a proxy to a class. I did manage this:
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
is now a Ring object that supports wrapping indices. The problem is that I'd have to define Ring objects like that every time. Is there a way to apply this proxy to the class such that calling new Ring()
returns it?
I have a simple ES6 class, like so:
class Ring extends Array {
insert (item, index) {
this.splice(index, 0, item);
return this;
}
}
I want to make it so that the indexing for Ring objects wraps, so that new Ring(1, 2, 3)[3]
returns 1, new Ring(1, 2, 3)[-1]
returns 3, and so on. Is this possible in ES6? If so, how would I implement it?
I've read about proxies, which allow a pletely customized getter, but I can't figure out how to apply a proxy to a class. I did manage this:
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
is now a Ring object that supports wrapping indices. The problem is that I'd have to define Ring objects like that every time. Is there a way to apply this proxy to the class such that calling new Ring()
returns it?
-
1
Just wrap
new Proxy (...)
with constructor function and call it withnew
. Yes, you can't do that without proxy. – Estus Flask Commented Oct 1, 2016 at 2:35
3 Answers
Reset to default 7Basically it is
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;
}
}
Warning: This is an ugly hack
This is a rather simple approach when you think about it.
function ClassToProxy(_class, handler) {
return (...args) => new Proxy(new _class(...args), handler);
}
This defined a function ClassToProxy
. The first argument is the class you want to add behavior too, and the second is the handler.
Here's example usage:
const Ring = ClassToProxy(
// Class
class Ring {
constructor(...items) {
this.items = items;
}
},
// Handler
{
get: function(target, name) {
return target.items[name];
}
}
)
You basically have two choices:
Wrap a
Proxy
around each instanceconst 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); } … }
wrap a
Proxy
around the prototype of your classclass 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]; } });
本文标签: ecmascript 6Custom Arraylike getter in JavaScriptStack Overflow
版权声明:本文标题:ecmascript 6 - Custom Array-like getter in JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741492302a2381677.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论