I have this copy array routine:
const copyArray = (a: HasIndex) => {
const ret = a.slice(0);
for (const [k, v] of Object.entries(a)) {
ret[k] = v;
}
return ret;
};
I assume that calling Array.prototype.slice will not copy over the prototype from the original?
So maybe I should do:
const copyArray = (a: HasIndex) => {
const ret = a.slice(0);
for (const [k, v] of Object.entries(a)) {
ret[k] = v;
}
Object.setPrototypeOf(ret, Object.getPrototypeOf(a)); // here?
return ret;
};
No, it's not necessary, slice() alone is sufficient, because it will call the constructor of the passed object. (If the object is an array, it'll call the Array constructor - otherwise, it'll call whatever constructor the object has.) See the specification:
- Let A be ArraySpeciesCreate(O, count).
(...assign to properties of A and return A)
where ArraySpeciesCreate is:
a. Let C be Get(originalArray, "constructor").
9.Return Construct(C, «length»).
In other words - if you call Array.prototype.slice on an array-like object whose prototype extends from Array but isn't Array.prototype, the passed object's constructor will be called. There's no need to set the prototype manually:
class ExtendedArray extends Array {
customMethod() {
console.log('custom method');
}
}
const e = new ExtendedArray();
const sliced = e.slice();
console.log(Object.getPrototypeOf(sliced) === ExtendedArray.prototype);
sliced.customMethod();
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