Как правильно унаследоваться от встроеных функций-конструкторов через прототипы?

Большинство конструкторов кидают ошибку, что вызываются без new. Array ошибку не кидает, посколбку можно вызывать и без new:

'use strict';

const RevercedArray = function(...args) {
  Array.apply(this, args);
};

Object.setPrototypeOf(RevercedArray.prototype, Array.prototype);

const arr = new RevercedArray(1, 2, 3);

console.log(arr); // RevercedArray {}

Я хочу сделать что-то похожее на это:

const Rectangle = function(x, y, width, height) {
  this.x = x;
  this.y = y;
  this.width = width;
  this.height = height;
};

Rectangle.prototype.area = function() {
  return this.width * this.height;
};

const Square = function(x, y, length) {
  Rectangle.call(this, x, y, length, length);
};

Object.setPrototypeOf(Square.prototype, Rectangle.prototype);

const sq = new Square(1, 2, 3);
console.log(sq); // Square { x: 1, y: 2, width: 3, height: 3 }

Ответы (1 шт):

Автор решения: Pavel Mayorov

Для этого вам пригодится метод Reflect.construct. Он как раз позволяет вызвать произвольную функцию так, как будто она была вызвана через new.

Таким образом, если вам очень важно унаследоваться от es6-класса через функцию и прототип, можно сделать примерно так:

function MyClass(…) {
    if (new.target === undefined) throw …;
    var obj = Reflect.construct(MyParent, […], new.target);
    
    // …

    return obj;
}
MyClass.prototype = Object.create(MyParent.prototype);

Однако, в 2024м году можно бы уже и на классы перейти.

→ Ссылка