I am trying to create a class that behaves a bit like an array. There are two things that I would like to have:
[index]
where index
is an integerMaking a class iterable is fairly easy:
class MyList {
constructor() {
this._list = [1, 2, 3];
}
[Symbol.iterator]() {
return this._list.values();
}
}
The above allows an instance of the class to be iterated over:
let myList = new MyList();
for (let item of myList) {
console.log(item); // prints out 1, 2, 3
}
Figuring out how to implement the second requirement turns out it's not as easy and the only think I found would be to extend Array
. But this means that I would have to override most of the methods inherited from Array
as I would need those methods to do something else than the built in behaviour.
Is there a way to achieve what I am asking? If so, what would be the best approach to do it?
Turns out you can store properties under integer-like string keys, e. g. foo['0'] = 'bar'
and access them with integers, e. g. foo[0] // => bar
. Assigning with an integer also works. Thanks to @JMM for pointing this stuff out.
Thus, the solution is as simple as:
class Foo {
constructor (...args) {
for (let i = 0; i < args.length; i++) {
this[i] = args[i];
}
}
[Symbol.iterator]() {
return Object
.keys(this)
.map(key => this[key])
.values();
}
}
const foo = new Foo('a', 'b', 'c');
for (let item of foo) {
console.log(item); // prints out a, b, c
}
console.log(foo[1]); // prints out b
Demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With