From 980fe00a74a9ad013b945755415ace2e5429c3c2 Mon Sep 17 00:00:00 2001
From: Alexey Pyltsyn Конструктор позволяет произвести начальную инициализацию, которая должна быть выполнена до того, как остальные методы будут вызваны. Если вы не определили метод constructor, то будет использован конструктор по умолчанию. Если ваш класс базовый, то конструктор по умолчанию пустой: Если ваш класс является производным классом, конструктор по умолчанию вызывает родительский конструктор, передавая любые аргументы, которые были предоставлены: Это позволяет работать следующему коду: Однако, если определён ваш собственный конструктор и класс является производным от какого-либо родительского класса, то вы должны явно объявить конструктор родительского класса, используя Данный фрагмент кода взят из classes sample (live demo). Посмотрите на этот отрывок кода. Если вы не определите метод constructor, будет использован constructor по умолчанию. Для базовых классов, constructor по умолчанию: Для производных классов, constructor по умолчанию: Первый способ определения класса — class declaration (объявление класса). Для этого необходимо воспользоваться ключевым словом Разница между объявлением функции (function declaration) и объявлением класса (class declaration) в том, что объявление функции совершает подъём ({{Glossary("Hoisting", "hoisting")}}), в то время как объявление класса — нет. Поэтому вначале необходимо объявить ваш класс и только затем работать с ним, а код же вроде следующего сгенерирует исключение типа {{jsxref("ReferenceError")}}: Второй способ определения класса — class expression (выражение класса). Можно создавать именованные и безымянные выражения. В первом случае имя выражения класса находится в локальной области видимости класса и может быть получено через свойства самого класса, а не его экземпляра. Смотрите также определение методов. Ключевое слово Когда статический или прототипный метод вызывается без привязки к this объекта (или когда this является типом boolean, string, number, undefined, null), тогда this будет иметь значение undefined внутри вызываемой функции. Автоупаковка не будет произведена. Поведение будет таким же как если бы мы писали код в нестрогом режиме. Если мы напишем этот же код используя классы основанные на функциях, тогда произойдёт автоупаковка основанная на значении this, в течение которого функция была вызвана. В строгом режиме автоупаковка не произойдёт - значение this останется прежним.Синтаксис
-constructor([arguments]) { ... }
+constructor([arguments]) { ... }
Описание
class Person {
+
class Person {
constructor(name) {
this.name = name;
@@ -38,17 +38,17 @@ otto.introduce();
constructor() {}
+constructor() {}
constructor(...args) {
+
constructor(...args) {
super(...args);
}
class ValidationError extends Error {
+
class ValidationError extends Error {
printCustomerMessage() {
return `Проверка не удалась :-( (подробности: ${this.message})`;
@@ -72,7 +72,7 @@ try {
super
. К примеру:class ValidationError extends Error {
+
class ValidationError extends Error {
constructor(message) {
super(message); // вызов конструктора родительского класса
@@ -106,7 +106,7 @@ try {
class Square extends Polygon {
+
class Square extends Polygon {
constructor(length) {
// Здесь вызывается конструктор родительского класса,
// в который передаётся length в качестве аргументов,
@@ -130,7 +130,7 @@ try {
class Polygon {
+
class Polygon {
constructor() {
this.name = "Polygon";
}
@@ -158,11 +158,11 @@ console.log(newInstance.name); //Polygon
constructor() {}
+constructor() {}
constructor(...args) {
+
constructor(...args) {
super(...args);
}
diff --git a/files/ru/web/javascript/reference/classes/index.html b/files/ru/web/javascript/reference/classes/index.html
index f8a63e92b2..742cd341ca 100644
--- a/files/ru/web/javascript/reference/classes/index.html
+++ b/files/ru/web/javascript/reference/classes/index.html
@@ -22,7 +22,7 @@ translation_of: Web/JavaScript/Reference/Classes
class
и указать имя класса (в примере — «Rectangle»).class Rectangle {
+
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
@@ -33,7 +33,7 @@ translation_of: Web/JavaScript/Reference/Classes
var p = new Rectangle(); // ReferenceError
+
@@ -41,7 +41,7 @@ class Rectangle {}var p = new Rectangle(); // ReferenceError
class Rectangle {}
// безымянный
+
// безымянный
var Rectangle = class {
constructor(height, width) {
this.height = height;
@@ -84,7 +84,7 @@ console.log(Rectangle.name);
class Rectangle {
+
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
@@ -107,7 +107,7 @@ console.log(square.area); // 100
static
, определяет статический метод или свойства для класса. Статические методы и свойства вызываются без инстанцирования их класса, и не могут быть вызваны у экземпляров (instance) класса. Статические методы, часто используются для создания служебных функций для приложения, в то время как статические свойства полезны для кеширования в рамках класса, фиксированной конфигурации или любых других целей, не связанных с реплецированием данных между экземплярами.class Point {
+
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
@@ -136,7 +136,7 @@ console.log(Point.distance(p1, p2)); // 7.0710678118654755
class Animal {
+
class Animal {
speak() {
return this;
}
@@ -156,7 +156,7 @@ eat(); // undefined
function Animal() { }
+
function Animal() { }
Animal.prototype.speak = function(){
return this;
@@ -178,7 +178,7 @@ eat(); // глобальный объект (нестрогий режим)Свойства экземпляра должны быть определены в методе класса:
class Rectangle { +class Rectangle { constructor(height, width) { this.height = height; this.width = width; @@ -187,7 +187,7 @@ eat(); // глобальный объект (нестрогий режим)Статические (class-side) свойства и свойства прототипа должны быть определены за рамками тела класса: -Rectangle.staticWidth = 20; +Rectangle.staticWidth = 20; Rectangle.prototype.prototypeWidth = 25;@@ -201,7 +201,7 @@ Rectangle.prototype.prototypeWidth = 25;Используя Javascript синтаксис определения полей, приведённый выше пример может быть изменён следующим образом:
-class Rectangle { +class Rectangle { height = 0; width; constructor(height, width) { @@ -218,7 +218,7 @@ Rectangle.prototype.prototypeWidth = 25;Предыдущий пример может быть изменён следующим образом, используя приватные поля:
-class Rectangle { +class Rectangle { #height = 0; #width; constructor(height, width) { @@ -241,7 +241,7 @@ Rectangle.prototype.prototypeWidth = 25;Ключевое слово
-extends
используется в объявлениях классов и выражениях классов для создания класса, дочернего относительно другого класса.class Animal { +
class Animal { constructor(name) { this.name = name; }
@@ -268,7 +268,7 @@ d.speak(); // Митци лаетАналогичным образом можно расширять традиционные, основанные на функциях "классы":
-function Animal (name) { +
function Animal (name) { this.name = name; } Animal.prototype.speak = function () { @@ -288,7 +288,7 @@ d.speak(); // Митци лает
Обратите внимание, что классы не могут расширять обычные (non-constructible) объекты. Если вам необходимо создать наследование от обычного объекта, в качестве замены можно использовать {{jsxref("Object.setPrototypeOf()")}}:
-var Animal = { +
var Animal = { speak() { console.log(
`${this.name} издаёт звук.`); } @@ -312,7 +312,7 @@ d.speak(); // Митци издаёт звук.
Например, при использовании таких методов, как {{jsxref("Array.map", "map()")}}, который возвращает конструктор по умолчанию, вам хотелось бы, чтобы они возвращали родительский объект
-Array
вместо объектаMyArray
. Символ {{jsxref("Symbol.species")}} позволяет это реализовать:class MyArray extends Array { +
class MyArray extends Array { // Изменить species на родительский конструктор Array static get [Symbol.species]() { return Array; } } @@ -326,7 +326,7 @@ console.log(mapped instanceof Array); // true
Ключевое слово
-super
используется для вызова функций на родителе объекта.class Cat { +
class Cat { constructor(name) { this.name = name; } @@ -355,7 +355,7 @@ l.speak();
Для реализации mix-ins в ECMAScript можно использовать функцию, которая в качестве аргумента принимает родительский класс, а возвращает подкласс, его расширяющий:
-var calculatorMixin = Base => class extends Base { +
var calculatorMixin = Base => class extends Base { calc() { } }; @@ -365,7 +365,7 @@ var randomizerMixin = Base => class extends Base {
Класс, использующий такие mix-ins, можно описать следующим образом:
-class Foo { } +
class Foo { } class Bar extends calculatorMixin(randomizerMixin(Foo)) { }
Спецификации
diff --git a/files/ru/web/javascript/reference/classes/private_class_fields/index.html b/files/ru/web/javascript/reference/classes/private_class_fields/index.html index 356e8b5517..597d98ebeb 100644 --- a/files/ru/web/javascript/reference/classes/private_class_fields/index.html +++ b/files/ru/web/javascript/reference/classes/private_class_fields/index.html @@ -10,7 +10,7 @@ original_slug: Web/JavaScript/Reference/Classes/Приватные_поля_клСинтаксис
-class ClassWithPrivateField { +class ClassWithPrivateField { #privateField } @@ -33,7 +33,7 @@ class ClassWithPrivateStaticField {Ограничение статических переменных, вызываемых только статическими методами, все ещё сохраняется.
-class ClassWithPrivateStaticField { +class ClassWithPrivateStaticField { static #PRIVATE_STATIC_FIELD static publicStaticMethod() { @@ -50,7 +50,7 @@ console.assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)Это может привести к неожиданному поведению при использовании this.
-class BaseClassWithPrivateStaticField { +class BaseClassWithPrivateStaticField { static #PRIVATE_STATIC_FIELD static basePublicStaticMethod() { @@ -76,7 +76,7 @@ console.assert(error instanceof TypeError)Инкапсуляция обеспечивается языком. Обращение к
-#
именам вне области видимости является синтаксической ошибкой.class ClassWithPrivateField { +class ClassWithPrivateField { #privateField constructor() { @@ -99,7 +99,7 @@ instance.#privateField === 42 // Syntax errorПриватные статические методы могут быть генераторами, асинхронными функциями и асинхронными функциями-генераторами.
-class ClassWithPrivateStaticMethod { +class ClassWithPrivateStaticMethod { static #privateStaticMethod() { return 42 } @@ -119,7 +119,7 @@ console.assert(ClassWithPrivateStaticMethod.publicStaticMethod2() === 42);Это может привести к неожиданному поведению при его использовании
-this
. В следующем примереthis
относится к классуDerived
(а не к классуBase
), когда мы пытаемся вызватьDerived.publicStaticMethod2()
, и, таким образом, имеет такое же "ограничение по происхождению", как упоминалось выше:class Base { +class Base { static #privateStaticMethod() { return 42; } @@ -141,7 +141,7 @@ console.log(Derived.publicStaticMethod2()); // TypeErrorПриватные методы экземпляров это методы, доступные у экземпляров класса, доступ к которым запрещён также, как у приватных полей класса.
-class ClassWithPrivateMethod { +class ClassWithPrivateMethod { #privateMethod() { return 'hello world' } @@ -157,7 +157,7 @@ console.log(instance.getPrivateMessage())Приватные методы экземпляров могут быть генератором, async, или функциями async генератора. Приватные геттеры и сеттеры также возможны:
-class ClassWithPrivateAccessor { +class ClassWithPrivateAccessor { #message get #decoratedMessage() { diff --git a/files/ru/web/javascript/reference/classes/public_class_fields/index.html b/files/ru/web/javascript/reference/classes/public_class_fields/index.html index 865babfded..0c4eb7a7ea 100644 --- a/files/ru/web/javascript/reference/classes/public_class_fields/index.html +++ b/files/ru/web/javascript/reference/classes/public_class_fields/index.html @@ -47,7 +47,7 @@ class ClassWithPublicInstanceMethod {Публичные статические поля объявляются при помощи ключевого слова
-static
. Они добавляются в конструктор класса во время его создания с помощью {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. Доступ также осуществляется через конструктор класса.class ClassWithStaticField { +class ClassWithStaticField { static staticField = 'static field'; } @@ -57,7 +57,7 @@ console.log(ClassWithStaticField.staticField);Поля без инициализации имеют значение
-undefined
.class ClassWithStaticField { +class ClassWithStaticField { static staticField; } @@ -67,7 +67,7 @@ console.log(ClassWithStaticField.staticField);Публичные статические поля не переопределяются в наследниках класса, а могут быть доступны через иерархию прототипов.
-class ClassWithStaticField { +class ClassWithStaticField { static baseStaticField = 'base field'; } @@ -83,7 +83,7 @@ console.log(SubClassWithStaticField.baseStaticField);При определении полей
-this
ссылается на конструктор класса. Также можно обратиться к нему по имени и использоватьsuper
для получения конструктора базового класса, если он существует.class ClassWithStaticField { +class ClassWithStaticField { static baseStaticField = 'base static field'; static anotherBaseStaticField = this.baseStaticField; @@ -108,7 +108,7 @@ console.log(SubClassWithStaticField.subStaticField);Публичные поля экземпляра добавляются через {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} либо перед тем, как будет исполнено тело конструктора в базовом классе, либо после того, как завершится
-super()
в классе наследнике.class ClassWithInstanceField { +class ClassWithInstanceField { instanceField = 'instance field'; } @@ -118,7 +118,7 @@ console.log(instance.instanceField);Поля без инициализации имеют значение
-undefined
.class ClassWithInstanceField { +class ClassWithInstanceField { instanceField; } @@ -129,7 +129,7 @@ console.log(instance.instanceField);Как и свойства, названия полей могут вычисляться.
-const PREFIX = 'prefix'; +const PREFIX = 'prefix'; class ClassWithComputedFieldName { [`${PREFIX}Field`] = 'prefixed field'; @@ -141,7 +141,7 @@ console.log(instance.prefixField);При определении полей
-this
ссылается на создающийся экземпляр класса. Как и в публичных методах экземпляра, получить доступ к прототипу базового класса можно с помощьюsuper
.class ClassWithInstanceField { +class ClassWithInstanceField { baseInstanceField = 'base field'; anotherBaseInstanceField = this.baseInstanceField; baseInstanceMethod() { return 'base method output'; } @@ -166,7 +166,7 @@ console.log(sub.subInstanceField);Ключевое слово
-static
объявляет статический метод класса. Статические методы не вызываются из экземпляра, вместо этого они вызывается из самого класса. Чаще всего это какие-либо служебные функции, такие как функции создания или копирования объектов.class ClassWithStaticMethod { +class ClassWithStaticMethod { static staticMethod() { return 'static method has been called.'; } @@ -182,7 +182,7 @@ console.log(ClassWithStaticMethod.staticMethod());Как и следует из названия, публичные методы экземпляра это методы, доступные для вызова из экземпляров.
-class ClassWithPublicInstanceMethod { +class ClassWithPublicInstanceMethod { publicMethod() { return 'hello world'; } @@ -196,7 +196,7 @@ console.log(instance.publicMethod());Вы можете использовать генераторы, асинхронные функции и асинхронные генераторы.
-class ClassWithFancyMethods { +class ClassWithFancyMethods { *generatorMethod() { } async asyncMethod() { } async *asyncGeneratorMethod() { } @@ -205,7 +205,7 @@ console.log(instance.publicMethod());Внутри методов экземпляра,
-this
ссылается на сам экземпляр.
В классах наследниках,super
даёт доступ к прототипу базового класса, позволяя вызывать его методы.class BaseClass { +class BaseClass { msg = 'hello world'; basePublicMethod() { return this.msg; @@ -225,7 +225,7 @@ console.log(instance.subPublicMethod());Геттеры и сеттеры это специальные методы, которые привязаны к свойствам класса и которые вызываются, когда к свойству обращаются или записывают. Используйте get и set для объявления публичных геттеров и сеттеров экземпляра.
-class ClassWithGetSet { +class ClassWithGetSet { #msg = 'hello world'; get msg() { return this.#msg; -- cgit v1.2.3-54-g00ecf