diff --git a/1-js/09-classes/01-class/1-rewrite-to-class/task.md b/1-js/09-classes/01-class/1-rewrite-to-class/task.md index 4477de679..982872108 100644 --- a/1-js/09-classes/01-class/1-rewrite-to-class/task.md +++ b/1-js/09-classes/01-class/1-rewrite-to-class/task.md @@ -2,8 +2,8 @@ importance: 5 --- -# Rewrite to class +# Перепишіть клас -The `Clock` class (see the sandbox) is written in functional style. Rewrite it in the "class" syntax. +Клас `Clock` написано в функціональному стилі. Перепишіть його в синтаксис класу. -P.S. The clock ticks in the console, open it to see. +P.S. Годинник тікає у консолі, відкрийте її, щоб побачити. diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index d19b9ca9a..93474b143 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -1,22 +1,22 @@ -# Class basic syntax +# Базовий синтаксис класу -```quote author="Wikipedia" -In object-oriented programming, a *class* is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). +```quote author="Вікіпедія" +В об’єктно-орієнтованому програмуванні, *клас* -- це спеціальна конструкція, яка використовується для групування пов’язаних змінних та функцій. При цьому, згідно з термінологією ООП, глобальні змінні класу (члени-змінні) називаються полями даних (також властивостями або атрибутами), а члени-функції називають методами класу. ``` -In practice, we often need to create many objects of the same kind, like users, or goods or whatever. +На практиці ми часто повинні створювати багато об’єктів одного й того ж виду, наприклад користувачів, або товари чи що завгодно. -As we already know from the chapter , `new function` can help with that. +Як ми вже знаємо з розділу , `new function` може допомогти з цим. -But in the modern JavaScript, there's a more advanced "class" construct, that introduces great new features which are useful for object-oriented programming. +Але в сучасному JavaScript існує більш просунута конструкція "клас", яка вводить нові чудові функції, які корисні для об’єктно-орієнтованого програмування. -## The "class" syntax +## Синтаксис "class" -The basic syntax is: +Основний синтаксис: ```js class MyClass { - // class methods + // методи класу constructor() { ... } method1() { ... } method2() { ... } @@ -25,11 +25,11 @@ class MyClass { } ``` -Then use `new MyClass()` to create a new object with all the listed methods. +Потім використовуйте `new MyClass()`, щоб створити новий об’єкт з усіма перерахованими методами. -The `constructor()` method is called automatically by `new`, so we can initialize the object there. +Метод `constructor()` викликається автоматично за допомогою `new`, в ньому ми можемо ініціалізувати об’єкт. -For example: +Наприклад: ```js run class User { @@ -44,33 +44,33 @@ class User { } -// Usage: -let user = new User("John"); +// Використання: +let user = new User("Іван"); user.sayHi(); ``` -When `new User("John")` is called: -1. A new object is created. -2. The `constructor` runs with the given argument and assigns it to `this.name`. +Коли `new User("John")` викликається: +1. Створюється новий об’єкт. +2. `constructor` запускається з даними аргументом і присвоює його `this.name`. -...Then we can call object methods, such as `user.sayHi()`. +...Потім ми можемо викликати методи об’єкту, такі як `user.sayHi()`. -```warn header="No comma between class methods" -A common pitfall for novice developers is to put a comma between class methods, which would result in a syntax error. +```warn header="Кома між методами класу не потрібна" +Часта помилка для розробників-початківців полягає в тому, щоб поставити кому між методами класу, що призведе до помилки синтаксису. -The notation here is not to be confused with object literals. Within the class, no commas are required. +Позначення тут не слід плутати з літералами об’єктів. У межах класу не треба ставити кому. ``` -## What is a class? +## Що таке клас? -So, what exactly is a `class`? That's not an entirely new language-level entity, as one might think. +Отже, що саме -- `class`? Він не є цілком новим ступенем мови програмування, як можна подумати. -Let's unveil any magic and see what a class really is. That'll help in understanding many complex aspects. +Розкриймо будь-яку магію і подивимося, що дійсно таке клас. Це допоможе в розумінні багатьох складних аспектів. -In JavaScript, a class is a kind of function. +У JavaScript клас є своєрідною функцією. -Here, take a look: +Погляньте на це: ```js run class User { @@ -78,24 +78,24 @@ class User { sayHi() { alert(this.name); } } -// proof: User is a function +// доказ: User -- це функція *!* alert(typeof User); // function */!* ``` -What `class User {...}` construct really does is: +Що конструкція `class User {...}` дійсно робить: -1. Creates a function named `User`, that becomes the result of the class declaration. The function code is taken from the `constructor` method (assumed empty if we don't write such method). -2. Stores class methods, such as `sayHi`, in `User.prototype`. +1. Створює функцію, що називається `User` та стає результатом оголошення класу. Код функції береться з методу `constructor` (приймається порожнім, якщо ми не написали такий метод). +2. Зберігає методи класу, такі як `sayHi`, `User.prototype`. -After `new User` object is created, when we call its method, it's taken from the prototype, just as described in the chapter . So the object has access to class methods. +Після того, як `new User` створився, коли ми викликаємо його метод, він береться з прототипу, як описано в розділі . Таким чином, об’єкт має доступ до методів класу. -We can illustrate the result of `class User` declaration as: +Ми можемо проілюструвати результат оголошення `class User` наступним чином: ![](class-user.svg) -Here's the code to introspect it: +Ось код, щоб проаналізувати це: ```js run class User { @@ -103,50 +103,50 @@ class User { sayHi() { alert(this.name); } } -// class is a function +// клас -- це функція alert(typeof User); // function -// ...or, more precisely, the constructor method +// ...або, точніше, метод конструктора alert(User === User.prototype.constructor); // true -// The methods are in User.prototype, e.g: -alert(User.prototype.sayHi); // the code of the sayHi method +// Методи знаходяться в User.prototype, наприклад: +alert(User.prototype.sayHi); // код sayHi методу -// there are exactly two methods in the prototype +// у прототипі існує рівно два методи alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi ``` -## Not just a syntactic sugar +## Не просто синтаксичний цукор -Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all: +Іноді люди кажуть, що `class` -- це "синтаксичний цукор" (синтаксис, який призначений для того, щоб зробити речі легше для читання, але не вводить нічого нового), тому що ми могли б фактично оголосити те ж саме взагалі без ключового слова `class`: ```js run -// rewriting class User in pure functions +// переписування класу User в чистих функціях -// 1. Create constructor function +// 1. Створити функцію-конструктор function User(name) { this.name = name; } -// a function prototype has "constructor" property by default, -// so we don't need to create it +// прототип функції має властивість "constructor" за замовчуванням, +// тому нам не потрібно її створювати -// 2. Add the method to prototype +// 2. Додати метод до прототипу User.prototype.sayHi = function() { alert(this.name); }; -// Usage: -let user = new User("John"); +// Використання: +let user = new User("Іван"); user.sayHi(); ``` -The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntactic sugar to define a constructor together with its prototype methods. +Результат цього оголошення дуже схожий. Отже, дійсно існують причини, чому `class` можна вважати синтаксичним цукром для того, щоб визначити конструктор разом із методами прототипу. -Still, there are important differences. +Проте, існують важливі відмінності. -1. First, a function created by `class` is labelled by a special internal property `[[IsClassConstructor]]: true`. So it's not entirely the same as creating it manually. +1. По-перше, функція, що створена за допомогою `class`, позначена спеціальною внутрішньою власністю `[[IsClassConstructor]]: true`. Так що це не зовсім те ж саме, що і створити її вручну. - The language checks for that property in a variety of places. For example, unlike a regular function, it must be called with `new`: + Мовна перевіряє цю властивість у різних місцях. Наприклад, на відміну від звичайної функції, її треба викликати з `new`: ```js run class User { @@ -157,7 +157,7 @@ Still, there are important differences. User(); // Error: Class constructor User cannot be invoked without 'new' ``` - Also, a string representation of a class constructor in most JavaScript engines starts with the "class..." + Також, представлення конструктора класу у вигляді рядка у більшості рушіїв JavaScript починається з "class..." ```js run class User { @@ -166,55 +166,55 @@ Still, there are important differences. alert(User); // class User { ... } ``` - There are other differences, we'll see them soon. + Є також інші відмінності, ми побачимо їх найближчим часом. -2. Class methods are non-enumerable. - A class definition sets `enumerable` flag to `false` for all methods in the `"prototype"`. +2. Методи класу неперелічувані. + Оголошення класу встановлює `enumerable` прапор у `false` для всіх методів в `"prototype"`. - That's good, because if we `for..in` over an object, we usually don't want its class methods. + Це добре тому, що коли ми проходимо через об’єкт за допомогою `for..in`, ми зазвичай не хочемо мати справу з методами класу. -3. Classes always `use strict`. - All code inside the class construct is automatically in strict mode. +3. Клас завжди `use strict`. + Весь код всередині конструкції класу автоматично знаходиться в строгому режимі. -Besides, `class` syntax brings many other features that we'll explore later. +Крім того, синтаксис `class` приносить багато інших особливостей, які ми дослідимо пізніше. ## Class Expression -Just like functions, classes can be defined inside another expression, passed around, returned, assigned, etc. +Так само, як функції, класи можуть бути визначені всередині іншого виразу, передані, повернуті, присвоєні та ін. -Here's an example of a class expression: +Ось приклад class expression: ```js let User = class { sayHi() { - alert("Hello"); + alert("Привіт"); } }; ``` -Similar to Named Function Expressions, class expressions may have a name. +Подібно до Named Function Expression, class expression може мати назву. -If a class expression has a name, it's visible inside the class only: +Якщо class expression має назву, то її видно лише у класі: ```js run // "Named Class Expression" -// (no such term in the spec, but that's similar to Named Function Expression) +// (немає такого терміну у специфікації, але це схоже на Named Function Expression) let User = class *!*MyClass*/!* { sayHi() { - alert(MyClass); // MyClass name is visible only inside the class + alert(MyClass); // назву MyClass видно тільки всередині класу } }; -new User().sayHi(); // works, shows MyClass definition +new User().sayHi(); // працює, показує визначення MyClass -alert(MyClass); // error, MyClass name isn't visible outside of the class +alert(MyClass); // помилка, назву MyClass не видно за межами класу ``` -We can even make classes dynamically "on-demand", like this: +Ми можемо навіть зробити класи динамічними "на вимогу", наприклад: ```js run function makeClass(phrase) { - // declare a class and return it + // оголошуємо клас і повертаємо його return class { sayHi() { alert(phrase); @@ -222,24 +222,24 @@ function makeClass(phrase) { }; } -// Create a new class -let User = makeClass("Hello"); +// Створюємо новий клас +let User = makeClass("Привіт"); -new User().sayHi(); // Hello +new User().sayHi(); // Привіт ``` -## Getters/setters +## Геттери/сеттери -Just like literal objects, classes may include getters/setters, computed properties etc. +Подібно до літералів об’єктів, класи можуть включати геттери/сеттери, обчислені назви властивостей тощо. -Here's an example for `user.name` implemented using `get/set`: +Ось приклад для `user.name`, що реалізований за допомогою `get/set`: ```js run class User { constructor(name) { - // invokes the setter + // викликає сеттер this.name = name; } @@ -253,7 +253,7 @@ class User { set name(value) { */!* if (value.length < 4) { - alert("Name is too short."); + alert("Ім’я занадто коротке."); return; } this._name = value; @@ -261,17 +261,17 @@ class User { } -let user = new User("John"); -alert(user.name); // John +let user = new User("Іван"); +alert(user.name); // Іван -user = new User(""); // Name is too short. +user = new User(""); // Ім’я занадто коротке. ``` -Technically, such class declaration works by creating getters and setters in `User.prototype`. +Технічно, таке оголошення класу працює шляхом створення геттерів та сеттерів в `User.prototype`. -## Computed names [...] +## Обчислені назви [...] -Here's an example with a computed method name using brackets `[...]`: +Ось приклад з обчисленою назвою методу за допомогою використання дужок `[...]`: ```js run class User { @@ -279,7 +279,7 @@ class User { *!* ['say' + 'Hi']() { */!* - alert("Hello"); + alert("Привіт"); } } @@ -287,71 +287,71 @@ class User { new User().sayHi(); ``` -Such features are easy to remember, as they resemble that of literal objects. +Такі особливості легко запам’ятати, оскільки вони нагадують літерали об’єктів. -## Class fields +## Поля класу -```warn header="Old browsers may need a polyfill" -Class fields are a recent addition to the language. +```warn header="Старим браузерам може знадобитися поліфіл" +Поля класу -- це недавнє доповнення до мови. ``` -Previously, our classes only had methods. +Раніше наші класи мали лише методи. -"Class fields" is a syntax that allows to add any properties. +"Поля класу" -- це синтаксис, який дозволяє додавати будь-які властивості. -For instance, let's add `name` property to `class User`: +Наприклад, додаймо властивість `name` до `class User`: ```js run class User { *!* - name = "John"; + name = "Іван"; */!* sayHi() { - alert(`Hello, ${this.name}!`); + alert(`Привіт, ${this.name}!`); } } -new User().sayHi(); // Hello, John! +new User().sayHi(); // Привіт, Іван! ``` -So, we just write " = " in the declaration, and that's it. +Отже, ми просто пишемо " = " в оголошенні, і це все. -The important difference of class fields is that they are set on individual objects, not `User.prototype`: +Важливою відмінністю полів класу є те, що вони встановлюються на окремих об’єктах, а не в `User.prototype`: ```js run class User { *!* - name = "John"; + name = "Іван"; */!* } let user = new User(); -alert(user.name); // John +alert(user.name); // Іван alert(User.prototype.name); // undefined ``` -We can also assign values using more complex expressions and function calls: +Ми також можемо присвоїти значення, використовуючи складніші вирази та виклики функції: ```js run class User { *!* - name = prompt("Name, please?", "John"); + name = prompt("Ім’я, будь ласка?", "Іван"); */!* } let user = new User(); -alert(user.name); // John +alert(user.name); // Іван ``` -### Making bound methods with class fields +### Створення методів, що пов’язані з полями класу -As demonstrated in the chapter functions in JavaScript have a dynamic `this`. It depends on the context of the call. +Як показано в розділі , функції в JavaScript мають динамічний `this`. Він залежить від контексту виклику. -So if an object method is passed around and called in another context, `this` won't be a reference to its object any more. +Отже, якщо метод об’єкта передається і викликається в іншому контексті, `this` більше не буде посиланням на цей об’єкт. -For instance, this code will show `undefined`: +Наприклад, цей код покаже `undefined`: ```js run class Button { @@ -364,21 +364,21 @@ class Button { } } -let button = new Button("hello"); +let button = new Button("привіт"); *!* setTimeout(button.click, 1000); // undefined */!* ``` -The problem is called "losing `this`". +Ця проблема називається "втратою `this`". -There are two approaches to fixing it, as discussed in the chapter : +Існує два підходи до розв'язання цієї проблеми, як обговорювалося в розділі : -1. Pass a wrapper-function, such as `setTimeout(() => button.click(), 1000)`. -2. Bind the method to object, e.g. in the constructor. +1. Передати функцію-обгортку, наприклад `setTimeout(() => button.click(), 1000)`. +2. Зв’язати метод з об’єктом за допомогою функції `bind`, наприклад у конструкторі. -Class fields provide another, quite elegant syntax: +Поля класу надають інший, досить елегантний синтаксис: ```js run class Button { @@ -392,37 +392,37 @@ class Button { */!* } -let button = new Button("hello"); +let button = new Button("привіт"); -setTimeout(button.click, 1000); // hello +setTimeout(button.click, 1000); // привіт ``` -The class field `click = () => {...}` is created on a per-object basis, there's a separate function for each `Button` object, with `this` inside it referencing that object. We can pass `button.click` around anywhere, and the value of `this` will always be correct. +Поле класу `click = () => {...}` створюється на основі конкретного об’єкта, існує окрема функція для кожного об’єкта `Button`, з `this` всередині неї, що посилається на цей об’єкт. Ми можемо передати кнопку куди завгодно, а значення `this` завжди буде коректним. -That's especially useful in browser environment, for event listeners. +Це особливо корисно в середовищі браузера, для слухачів подій. -## Summary +## Підсумки -The basic class syntax looks like this: +Основний синтаксис класу виглядає так: ```js class MyClass { - prop = value; // property + prop = value; // властивість - constructor(...) { // constructor + constructor(...) { // конструктор // ... } - method(...) {} // method + method(...) {} // метод - get something(...) {} // getter method - set something(...) {} // setter method + get something(...) {} // геттер метод + set something(...) {} // сеттер метод - [Symbol.iterator]() {} // method with computed name (symbol here) + [Symbol.iterator]() {} // метод з обчисленим ім’ям (символом в цьому випадку) // ... } ``` -`MyClass` is technically a function (the one that we provide as `constructor`), while methods, getters and setters are written to `MyClass.prototype`. +`MyClass` технічно є функцією (тою, яку ми надаємо як `constructor`), тоді як методи, геттери та сеттери записуються до `MyClass.prototype`. -In the next chapters we'll learn more about classes, including inheritance and other features. +У наступних розділах ми дізнаємося більше про класи, включаючи наслідування та інші особливості. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy