JS-инженер Андреа Джаммарки написал на medium.com пост, в котором назвал заблуждением утверждение, что классы JS — это просто синтаксический сахар для прототипного наследования. По его мнению, есть множество вещей, которые можно смоделировать с помощью ES5 и прототипного наследования, но ни один из этих методов не настолько быстрый и безопасный, как использование соответствующего синтаксиса для классов JS.
Вот как он обосновал позицию в пользу использования классов JS:
use strict в ES5 не запрещает вызов конструкторов без служебного слова new.// ES5
function Test() { "use strict"; }
Test.call({}); // it's OK
// ES6+
class Test {}
Test.call({}); // it throws Современные классы имеют свойство new.target, которое невозможно сымитировать в ES5 без использования транспайлера, копирующего такое поведение.
// ES5 epic fail
function List() { "use strict"; }
List.prototype = Object.create(Array.prototype);
var list = new List;
list.push(1, 2, 3);
JSON.stringify(list);
// {"0":1,"1":2,"2":3,"length":3}
list.slice(0) instanceof List; // false По словам автора, он не использует в конструкторе свойство Array.apply(this, arguments), так как расширение массива ES5 неудобно.
// ES5 epic fail v2
function Text(value) {
"use strict";
String.call(this, value);
}
new Text("does this work?");
// nope, it doesn't ... no way it can. С помощью прототипного наследования не получится расширить String, а с помощью классов JS можно
list.slice (0) не является экземпляром List из-за свойства Symbol.species// ES6+
class List extends Array {}
(new List).slice(0) instanceof List; // true
[].slice.call(new List) instanceof List; // true Array.apply(this, arguments), потому что:— встроенный массив создает новый массив, которому не важен контекст и другие встроенные функции;
— классы JS обновляют экземпляры, что невозможно сделать в ES5 без транспайлера.
// ES5
function Button() {
return document.createElement('button');
}
function MyButton(value) {
Button.call(this);
this.textContent = value;
}
Object.setPrototypeOf(MyButton, Button);
Object.setPrototypeOf(MyButton.prototype, Button.prototype); new MyButton(“content”) возвращается экземпляр MyButton со свойством textContent.function MySubClass() {
var self = Class.apply(this, arguments) || this;
// do anything with the self
return self;
} Этот подход плох тем, что:
— если суперкласс возвращает что-то еще, теряется наследование;
— если суперкласс является встроенным, вместо этого может быть команда self, указывающая на примитив.
Как в этом случае работают классы JS:
// ES6+
class Button {
constructor() {
return document.createElement('button');
}
}
class MyButton extends Button {
constructor(value) {
super();
this.textContent = value;
}
}
document.body.appendChild(new MyButton("hello")); // ES6+
class Test {
method() {}
}
new Test.prototype.method;
// TypeError: Test.prototype.method is not a constructor В ES5 все функции могут использоваться как конструкторы.
// ES5
function Test() {}
Test.prototype.method = function () {
if (!(this instanceof Test))
throw new TypeError("not a constructor");
}; // ES5
function WithArrows() {
Object.defineProperties(this, {
method1: {
configurable: true,
writable: true,
value: () => "arrow 1"
}
});
}
// ES6+
class WithArrows {
method1 = () => "arrow 1";
}
// (new WithArrows).method1(); // ES6+
class WithPrivates {
#value;
#method(value) {
this.#value = value;
}
constructor(value) {
this.#method(value);
}
} В ES5 можно смоделировать частные свойства, только используя транспайлер и коллекции WeakMap.
Автор призывает перестать называть классы JS просто «синтаксическим сахаром». По мнению Андреа Джаммарки, множество вещей можно симулировать с помощью прототипного наследования, но некоторые просто невозможно. Использование современных классов из ES6 поможет создать лучшее ООП в JS, чем оно было в течение последних 20 лет.
На фоне роста спроса на ликвидность в бычьем рынке 2025 года, криптозаймы снова выходят на…
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…