Reputation: 390
Proxies can be used to define 'general getters' for objects. For example
var obj = {'a':3, 'b':4 };
var proxy = new Proxy( obj, {
get: function(obj, prop){return obj[prop]+10}
} );
proxy.a //13
I have a vector class that extends Array
:
class vec extends Array{
constructor(...a){
super(...a)
}
get x(){
return this[0];
}
/* some more functions */
}
and I want the index to wrap around like in python. For example if v
is a vector I want v[-1]
to return the last element of v
. To do this I would need to wrap a proxy around each vector instance (I think) so I could clamp the index. But I don't know how to make a proxy for all instances I only know how it works for a single object. So how would you do this?
Upvotes: 2
Views: 3159
Reputation: 664569
I want
v[-1]
to return the last element ofv
.
It seems your Vector
has a fixed size (e.g. 3 for .x
, .y
and .z
) so you could just define another getter with the name -1
.
In general, I'd recommend to follow the relative indexing proposal and just implement an .at()
method, or the array .last
proposal.
I don't know how to make a proxy for all instances
You can make your prototype a proxy:
vec.prototype = new Proxy(vec.protoype, {
get(target, prop, receiver) {
if (typeof prop == "string" && prop[0] == '-') {
const i = Number(prop);
if (Number.isInteger(i)) {
return receiver[receiver.length + i];
}
}
return Reflect.get(target, prop, receiver)
}
});
Upvotes: 1
Reputation: 122047
You could create your class so that it returns a instance of a proxy, and on that proxy you create a get method where you add your custom logic.
class Vec extends Array {
constructor(...a) {
super(...a)
return new Proxy(this, {
get: function(target, prop, receiver) {
const n = +prop;
if (!isNaN(n) && n < 0) {
return [...target].slice(n)
}
return Reflect.get(...arguments);
}
})
}
get x() {
return this[0];
}
}
const v = new Vec(1, 2, 3);
console.log(v[-1])
console.log(v[-2])
console.log(v.x)
Upvotes: 3