Reputation: 100322
I know I could create my own Number
class by overriding valueOf
function MyNumber(n)
{
this.n = n;
}
MyNumber.prototype.valueOf = function() { return this.n; };
Then I could do this:
var n = new MyNumber(10);
console.log(n + 1); // 11
I want to know how I could access each value by index, like this
function MyArray(a)
{
this.a = a;
}
MyArray.prototype.valueOf = function() { return this.a; };
var a = new MyArray([1, 2, 3]);
console.log(a[0])
Is it possible? How?
Upvotes: 3
Views: 463
Reputation: 12388
You can do it by returning a Proxy from your constructor.
class ArrayLike {
data = [];
constructor(...args) {
this.data.push(...args)
return new Proxy(this, {
get: function(target, prop, receiver) {
const n = +prop;
// Number access works like array index
if (!isNaN(n)) {
return target.data[n];
}
// Other access passes through
return Reflect.get(target, prop, receiver);
}
});
}
get length() {
return this.data.length;
}
}
const notArray = new ArrayLike("a", "b", "c");
console.log(notArray[0])
console.log(notArray[1])
console.log(notArray.length)
This class in this example won't have the other array methods.
The answer to another question shows a way to extend the native Array, and make negative indices return from the end of the array.
Upvotes: 0
Reputation: 81988
That's as simple as a for... in
loop:
function MyArray(a)
{
this.a = a;
for(var it in a) this[it] = a[it];
}
Actually, jQuery does something very much like this which is why you can do something like $('body')[0]
and get the body
tag. The jQuery object, when it has received the return of the seletor query, goes through each of those indexes and maps it to this[i] = <selected node>
. And while Arrays do have a special length
property, that type of assignment will get you most of the way there.
Upvotes: 4
Reputation: 198324
You can't overload indexing operator (or any operator) in JavaScript.
You could imitate it by making MyArray
constructor copy a[i]
to this[i]
, but you won't get the magic of length
.
Upvotes: 4