Как использовать классы в JavaScript

12 set 2022 4 min di lettura
Как использовать классы в JavaScript
Indice dei contenuti

Введение

JavaScript — это язык, основанный на прототипах, и каждый объект в JavaScript имеет скрытое внутреннее свойство, называемое [[Prototype]], которое можно использовать для расширения свойств и методов объекта.

Спецификация языка ECMAScript 2015, часто называемая ES6, представила классы на языке JavaScript. Классы в JavaScript на самом деле не предлагают никаких дополнительных функций и часто описываются как «синтаксический сахар» по сравнению с прототипами и наследованием, поскольку они предлагают более чистый и элегантный синтаксис. Поскольку в других языках программирования используются классы, синтаксис классов в JavaScript облегчает разработчикам переход между различными языками.

Классы — это функции

Класс JavaScript — это тип функции. Классы объявляются с помощью ключевого слова class. Мы будем использовать синтаксис выражения функции для инициализации функции и синтаксис выражения класса для инициализации класса.

//Initializing a function with a function expression
 const x = function() {}
//Initializing a class with a class expression
 const y = class {}

Мы можем получить доступ к [[Prototype]] объекта с помощью Object.getPrototypeOf(). Давайте используем его для тестирования пустой функции, которая у нас есть.

Object.getPrototypeOf(x);
ƒ () { [native code] }

Мы также можем использовать этот метод в только что созданном классе.

Object.getPrototypeOf(y);
ƒ () { [native code] }

Код, объявленный с function и class, возвращает функцию [[Prototype]]. С прототипами любая функция может стать экземпляром конструктора с использованием new ключевого слова.

const x = function() {}

 //Initialize a constructor from a function
 const constructorFromFunction = new x();

 console.log(constructorFromFunction);
x {}
 constructor: ƒ ()

Это относится и к классам.

const y = class {}

 //Initialize a constructor from a class
 const constructorFromClass = new y();

 console.log(constructorFromClass);
y {}
 constructor: class

Эти примеры конструктора прототипа в остальном пусты, но мы можем видеть синтаксис, оба метода дают один и тот же конечный результат.

Определить класс

Функция- конструктор инициализируется рядом параметров, которые будут назначены как свойства this, ссылающиеся на саму функцию. По соглашению первая буква идентификатора должна быть заглавной.

//Initializing a constructor function
 function Hero(name, level) {
 this.name = name;
 this.level = level;
 }
конструктор.js

Когда мы переведем его в синтаксис класса, показанный ниже, мы увидим, что он устроен очень похоже.

//Initializing a class definition
 class Hero {
 constructor(name, level) {
 this.name = name;
 this.level = level;
 }
 }
class.js

Мы знаем, что функция конструктора должна быть планом объекта с первой буквой инициализатора в верхнем регистре (что необязательно). class ключевого слова более прямо передает цель нашей функции.

Единственная разница в синтаксисе инициализации заключается в использовании ключевого слова class вместо function при присвоении свойств в методе constructor().

Определите методы

Обычная практика с функциями-конструкторами заключается в назначении методов непосредственно prototype, а не инициализации, как показано в следующем методе greet().

function Hero(name, level) {
 this.name = name;
 this.level = level;
 }

 //Adding a method to the constructor
 Hero.prototype.greet = function() {
 return `${this.name} says hello.`;
 }
конструктор.js

В классах этот синтаксис упрощается, и метод можно добавить непосредственно в класс. Используя ярлык определения метода, представленный в ES6, определение метода становится еще более лаконичным процессом.

class Hero {
 constructor(name, level) {
 this.name = name;
 this.level = level;
 }

 //Adding a method to the constructor
 greet() {
 return `${this.name} says hello.`;
 }
 }
class.js

Давайте посмотрим на эти свойства и методы в действии. Мы создадим новый экземпляр Hero, используя new ключевое слово, и назначим некоторые значения.

const hero1 = new Hero('Varg', 1);

Если мы напечатаем больше информации о нашем новом объекте с помощью console.log(hero1), мы сможем увидеть больше деталей о том, что происходит с инициализацией класса.

Hero {name: "Varg", level: 1}
 __proto__:
 ▶ constructor: class Hero
 ▶ greet: ƒ greet()

В выводе мы видим, что функции constructor() и greet() были применены к __proto__ hero1 [[Prototype]], а не непосредственно как метод к объекту hero1. Хотя это очевидно при создании функций-конструкторов, это не очевидно при создании классов. Классы допускают более простой и лаконичный синтаксис, но при этом жертвуют некоторой ясностью процесса.

Расширить класс

Преимущество функций-конструкторов и классов заключается в том, что они могут быть расширены до новых схем объектов, основанных на родителях. Это предотвращает повторение кода для объектов, которые похожи, но требуют некоторых дополнительных или более специфических функций.

Новые функции-конструкторы могут быть созданы родителем с помощью метода call(). В приведенном ниже примере мы создадим более конкретный класс персонажей с именем Mage и назначим ему свойства Hero с помощью call(), а также добавим дополнительное свойство.

//Creating a new constructor from the parent
 function Mage(name, level, spell) {
 //Chain constructor with call
 Hero.call(this, name, level);

 this.spell = spell;
 }
конструктор.js

На этом этапе мы можем создать новый экземпляр Mage, используя те же свойства Hero и новое дополнение.

const hero2 = new Mage('Lejon', 2, 'Magic Missile');

hero2 из консоли, мы видим, что создали нового Mage на основе строителя.

Mage {name: "Lejon", level: 2, spell: "Magic Missile"}
 __proto__:
 ▶ constructor: ƒ Mage(name, level, spell)

В классах ES6 ключевое слово super используется вместо call для доступа к основным функциям. Мы будем использовать extends для ссылки на родительский (родительский) класс.

//Creating a new class from the parent
 class Mage extends Hero {
 constructor(name, level, spell) {
 //Chain constructor with super
 super(name, level);

 //Add a new property
 this.spell = spell;
 }
 }
class.js

Теперь мы можем таким же образом создать новый экземпляр Mage.

const hero2 = new Mage('Lejon', 2, 'Magic Missile');

Мы напечатаем hero2 на консоли и просмотрим вывод.

Mage {name: "Lejon", level: 2, spell: "Magic Missile"}
 __proto__: Hero
 ▶ constructor: class Mage

Вывод практически такой же, за исключением того, что в конструкторе класса [[Prototype]] он связан с родителем, в данном случае Hero.

Ниже представлено параллельное сравнение всего процесса инициализации, добавления методов и наследования функции-конструктора и класса.

function Hero(name, level) {
 this.name = name;
 this.level = level;
 }

 //Adding a method to the constructor
 Hero.prototype.greet = function() {
 return `${this.name} says hello.`;
 }

 //Creating a new constructor from the parent
 function Mage(name, level, spell) {
 //Chain constructor with call
 Hero.call(this, name, level);

 this.spell = spell;
 }
конструктор.js
//Initializing a class
 class Hero {
 constructor(name, level) {
 this.name = name;
 this.level = level;
 }

 //Adding a method to the constructor
 greet() {
 return `${this.name} says hello.`;
 }
 }

 //Creating a new class from the parent
 class Mage extends Hero {
 constructor(name, level, spell) {
 //Chain constructor with super
 super(name, level);

 //Add a new property
 this.spell = spell;
 }
 }
class.js

Хотя синтаксис сильно отличается, основной результат обоих методов почти одинаков. Классы дают нам более лаконичный способ создания чертежей объектов, а функции-конструкторы более точно описывают происходящее.

Вывод

В этом руководстве мы узнали о сходствах и различиях между функциями конструктора JavaScript и классами ES6. И классы, и конструкторы имитируют объектно-ориентированную модель наследования в JavaScript, который является языком наследования на основе прототипов.

Понимание прототипного наследования имеет решающее значение для того, чтобы быть эффективным разработчиком JavaScript. Знание классов чрезвычайно полезно, так как популярные библиотеки JavaScript, такие как React, часто используют синтаксис class.

Buy me a coffeeBuy me a coffee

Supportaci se ti piacciono i nostri contenuti. Grazie.

Successivamente, completa il checkout per l'accesso completo a Noviello.it.
Bentornato! Accesso eseguito correttamente.
Ti sei abbonato con successo a Noviello.it.
Successo! Il tuo account è completamente attivato, ora hai accesso a tutti i contenuti.
Operazione riuscita. Le tue informazioni di fatturazione sono state aggiornate.
La tua fatturazione non è stata aggiornata.