I have a custom array class that extends the base array class. I have a custom method for ease of use
export class ExampleArray extends Array {
includesThing(thing) {
...
return false
}
}
However the existing methods of filter
, map
etc return an instance of an array. I would like to return an instance of ExampleArray
with these methods.
I can find the interface for these methods, but not their implementation. How do I call the parent method and return my custom EampleArray instead? Something like the following
export class ExampleArray extends Array {
filter() {
result = Array.filter()
array = new ExampleArray()
array.push(...result)
return array
}
Or is this even the correct way to extend an Array to make a custom array?
You CANNOT extend the Array Object in JavaScript. Instead, what you can do is define an object that will contain a list of functions that perform on the Array, and inject these functions into that Array instance and return this new Array instance. What you shouldn't do is changing the Array.
Arrays are objects but an array type is not a class and therefore can't be extended.
By default, each class in Node. js can extend only a single class. That means, to inherit from multiple classes, you'd need to create a hierarchy of classes that extend each other. If you're with NPM v4 or lower, just append a -S to the install command to automatically add it to the dependencies in package.
You will need to shadow the existing .filter
and .map
so that, when called on an instance of ExampleArray
, your new functions will be called, rather than the Array.prototype
functions. Inside ExampleArray
, you can access super.map
and super.filter
in order to get to the Array.prototype
methods. For example:
class ExampleArray extends Array {
constructor(...args) {
super(...args);
}
hasMoreThanTwoItems() {
// example custom method
return this.length > 2;
}
isExampleArray() {
return true;
}
// Shadow Array.prototype methods:
filter(...args) {
return new ExampleArray(
// Spread the result of the native .filter into a new ExampleArray instance:
...super.filter.apply(this, args)
);
}
map(...args) {
return new ExampleArray(
...super.map.apply(this, args)
);
}
}
const exampleArray = new ExampleArray(3, 4, 5, 6, 7);
// true, filtering will result in 3 items
console.log(
exampleArray
.filter(e => e > 4)
.hasMoreThanTwoItems()
);
// false, filtering will result in zero items
console.log(
exampleArray
.filter(e => e > 10)
.hasMoreThanTwoItems()
);
// true, is an ExampleArray
console.log(
exampleArray
.map(e => e * 2)
.isExampleArray()
);
Note that there are also other Array methods which return arrays, including splice
, slice
, and (experimental) flat
and flatMap
. If you want those to return a custom class instantiation rather than the default Array
instance, follow the same pattern: shadow the Array.prototype
function name, and return a new ExampleArray
populated with the result of apply
ing the Array.prototype
method:
<fnName>(...args) {
return new ExampleArray(
...super.<fnName>.apply(this, args)
);
}
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