Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When calling Array.prototype.slice will the new array have the same prototype?

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;

};
like image 411
Alexander Mills Avatar asked Nov 18 '25 23:11

Alexander Mills


1 Answers

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:

  1. 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();
like image 146
CertainPerformance Avatar answered Nov 20 '25 15:11

CertainPerformance



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!