Declaring classes in javascript

class

The class declaration creates a binding of a new class to a given name.

You can also define classes using the class expression.

Try it

Syntax

class name  // class body > class name extends otherName  // class body > 

Description

The class body of a class declaration is executed in strict mode. The class declaration is very similar to let :

  • class declarations are scoped to blocks as well as functions.
  • class declarations can only be accessed after the line of declaration is reached (see temporal dead zone). For this reason, class declarations are commonly regarded as non-hoisted (unlike function declarations).
  • class declarations do not create properties on globalThis when declared at the top level of a script (unlike function declarations).
  • class declarations cannot be redeclared by any other declaration in the same scope.

Outside the class body, class declarations can be re-assigned like let , but you should avoid doing so. Within the class body, the binding is constant like const .

class Foo  static  Foo = 1; // TypeError: Assignment to constant variable. > > class Foo2  bar = (Foo2 = 1); // TypeError: Assignment to constant variable. > class Foo3 > Foo3 = 1; console.log(Foo3); // 1 

Examples

A simple class declaration

In the following example, we first define a class named Rectangle , then extend it to create a class named FilledRectangle .

Note that super() , used in the constructor , can only be used in constructors, and must be called before the this keyword can be used.

class Rectangle  constructor(height, width)  this.name = "Rectangle"; this.height = height; this.width = width; > > class FilledRectangle extends Rectangle  constructor(height, width, color)  super(height, width); this.name = "Filled rectangle"; this.color = color; > > 

Specifications

Browser compatibility

BCD tables only load in the browser

See also

Found a content problem with this page?

This page was last modified on Jul 3, 2023 by MDN contributors.

Your blueprint for a better internet.

Источник

Класс: базовый синтаксис

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

На практике нам часто надо создавать много объектов одного вида, например пользователей, товары или что-то ещё.

Как мы уже знаем из главы Конструктор, оператор «new», с этим может помочь new function .

Но в современном JavaScript есть и более продвинутая конструкция «class», которая предоставляет новые возможности, полезные для объектно-ориентированного программирования.

Синтаксис «class»

Базовый синтаксис выглядит так:

class MyClass < // методы класса constructor() < . >method1() < . >method2() < . >method3() < . >. >

Затем используйте вызов new MyClass() для создания нового объекта со всеми перечисленными методами.

При этом автоматически вызывается метод constructor() , в нём мы можем инициализировать объект.

class User < constructor(name) < this.name = name; >sayHi() < alert(this.name); >> // Использование: let user = new User("Иван"); user.sayHi();

Когда вызывается new User(«Иван») :

  1. Создаётся новый объект.
  2. constructor запускается с заданным аргументом и сохраняет его в this.name .

…Затем можно вызывать на объекте методы, такие как user.sayHi() .

Частая ошибка начинающих разработчиков – ставить запятую между методами класса, что приводит к синтаксической ошибке.

Синтаксис классов отличается от литералов объектов, не путайте их. Внутри классов запятые не требуются.

Что такое класс?

Итак, что же такое class ? Это не полностью новая языковая сущность, как может показаться на первый взгляд.

Давайте развеем всю магию и посмотрим, что такое класс на самом деле. Это поможет в понимании многих сложных аспектов.

В JavaScript класс – это разновидность функции.

class User < constructor(name) < this.name = name; >sayHi() < alert(this.name); >> // доказательство: User - это функция alert(typeof User); // function

Вот что на самом деле делает конструкция class User <. >:

  1. Создаёт функцию с именем User , которая становится результатом объявления класса. Код функции берётся из метода constructor (она будет пустой, если такого метода нет).
  2. Сохраняет все методы, такие как sayHi , в User.prototype .

При вызове метода объекта new User он будет взят из прототипа, как описано в главе F.prototype. Таким образом, объекты new User имеют доступ к методам класса.

На картинке показан результат объявления class User :

Можно проверить вышесказанное и при помощи кода:

class User < constructor(name) < this.name = name; >sayHi() < alert(this.name); >> // класс - это функция alert(typeof User); // function // . или, если точнее, это метод constructor alert(User === User.prototype.constructor); // true // Методы находятся в User.prototype, например: alert(User.prototype.sayHi); // sayHi() < alert(this.name); >// в прототипе ровно 2 метода alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi

Не просто синтаксический сахар

Иногда говорят, что class – это просто «синтаксический сахар» в JavaScript (синтаксис для улучшения читаемости кода, но не делающий ничего принципиально нового), потому что мы можем сделать всё то же самое без конструкции class :

// перепишем класс User на чистых функциях // 1. Создаём функцию constructor function User(name) < this.name = name; >// каждый прототип функции имеет свойство constructor по умолчанию, // поэтому нам нет необходимости его создавать // 2. Добавляем метод в прототип User.prototype.sayHi = function() < alert(this.name); >; // Использование: let user = new User("Иван"); user.sayHi();

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

Однако есть важные отличия:

    Во-первых, функция, созданная с помощью class , помечена специальным внутренним свойством [[IsClassConstructor]]: true . Поэтому это не совсем то же самое, что создавать её вручную. В отличие от обычных функций, конструктор класса не может быть вызван без new :

class User < constructor() <>> alert(typeof User); // function User(); // Error: Class constructor User cannot be invoked without 'new'

Кроме того, строковое представление конструктора класса в большинстве движков JavaScript начинается с «class …»

class User < constructor() <>> alert(User); // class User

Также в дополнение к основной, описанной выше, функциональности, синтаксис class даёт ряд других интересных возможностей, с которыми мы познакомимся чуть позже.

Class Expression

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

Пример Class Expression (по аналогии с Function Expression):

Аналогично Named Function Expression, Class Expression может иметь имя.

Если у Class Expression есть имя, то оно видно только внутри класса:

// "Named Class Expression" // (в спецификации нет такого термина, но происходящее похоже на Named Function Expression) let User = class MyClass < sayHi() < alert(MyClass); // имя MyClass видно только внутри класса >>; new User().sayHi(); // работает, выводит определение MyClass alert(MyClass); // ошибка, имя MyClass не видно за пределами класса

Мы даже можем динамически создавать классы «по запросу»:

function makeClass(phrase) < // объявляем класс и возвращаем его return class < sayHi() < alert(phrase); >; >; > // Создаём новый класс let User = makeClass("Привет"); new User().sayHi(); // Привет

Геттеры/сеттеры, другие сокращения

Как и в литеральных объектах, в классах можно объявлять вычисляемые свойства, геттеры/сеттеры и т.д.

Вот пример user.name , реализованного с использованием get/set :

class User < constructor(name) < // вызывает сеттер this.name = name; >get name() < return this._name; >set name(value) < if (value.length < 4) < alert("Имя слишком короткое."); return; >this._name = value; > > let user = new User("Иван"); alert(user.name); // Иван user = new User(""); // Имя слишком короткое.

При объявлении класса геттеры/сеттеры создаются на User.prototype , вот так:

Object.defineProperties(User.prototype, < name: < get() < return this._name >, set(name) < // . >> >);

Пример с вычисляемым свойством в скобках [. ] :

Источник

Читайте также:  Is javascript enabled on google chrome
Оцените статью