Skip to content

Fixed function prototype (01 08 02) #718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@

1. `true`.

Визначення `Rabbit.prototype` встановлює властивість `[[Prototype]]` для новоствореного об’єкта, але це жодним чином не впливає на вже існуючий об’єкт.
Перепризначення `Rabbit.prototype` встановлює властивість `[[Prototype]]` для об'єктів, які будуть створені після цього. Але воно жодним чином не впливає на вже існуючі об'єкти.

2. `false`.

Об’єкти призначаються шляхом посилання на них. Об’єкт з властивістю `Rabbit.prototype` не дублюється, це є той самий об’єкт на який посилаються як через `Rabbit.prototype` так і через властивість `[[Prototype]]` об’єкта `rabbit`.
Об’єкти призначаються шляхом посилання на них. Об’єкт з властивості `Rabbit.prototype` не дублювався. Це той самий об’єкт на який посилаються як через `Rabbit.prototype`, так і через властивість `[[Prototype]]` об’єкта `rabbit`.

А отже, коли ми змінюємо контент такого об’єкта через посилання, такі зміни стають видимі і через інші посилання.
А отже, коли ми змінюємо вміст такого об’єкта через посилання, такі зміни стають видимі і через інші посилання.

3. `true`.

Усі `delete` операції застосовуються безпосередньо на самому об'єкті. Тут `delete rabbit.eats` намагається видалити властивість `eats` з об’єкта `rabbit`, але такої властивості немає. А тому така операція не має ніякого ефекту.
Усі `delete` операції застосовуються лише безпосередньо до самого об'єкта. Тут `delete rabbit.eats` намагається видалити властивість `eats` з об’єкта `rabbit`, але такої властивості немає. А тому така операція не має ніякого ефекту.

4. `undefined`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ importance: 5

# Заміна властивості "prototype"

В коді, що показаний нижче, ми створюємо об’єкт `new Rabbit` і потім міняємо його прототип.
В коді, що показаний нижче, ми створюємо функцію-конструктор `new Rabbit` і потім змінюємо її `prototype`.

На початку, маємо цей код:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Так, ми можемо використовувати такий підхід якщо ми впевнені, що властивість `"constructor"` має правильне значення.

Для прикладу, якщо ми не чіпаємо властивість за замовчуванням `"prototype"`, тоді цей код буде працювати правильно:
Наприклад, якщо ми не чіпаємо властивість за замовчуванням `"prototype"`, тоді цей код буде працювати правильно:

```js run
function User(name) {
this.name = name;
}

let user = new User('John');
let user2 = new user.constructor('Pete');
let user = new User('Богдан');
let user2 = new user.constructor('Данило');

alert( user2.name ); // Pete (працює!)
alert( user2.name ); // Данило (працює!)
```

Код працює, тому що `User.prototype.constructor == User`.
Expand All @@ -27,23 +27,23 @@ function User(name) {
User.prototype = {}; // (*)
*/!*

let user = new User('John');
let user2 = new user.constructor('Pete');
let user = new User('Богдан');
let user2 = new user.constructor('Данило');

alert( user2.name ); // undefined
```

Чому `user2.name` є `undefined`?

Ось тут пояснення як `new user.constructor('Pete')` працює:
Ось тут пояснення як `new user.constructor('Данило')` працює:

1. Спочатку, здійснюється пошук у властивості `constructor` об’єкта `user`. Нічого не знаходять.
2. Потім переключаються на ланцюжок прототипу. Прототипом для об’єкта `user` є `User.prototype`, і він також не має властивості `constructor` (тому що ми "забули" визначити його правильним чином!).
2. Потім переключаються на ланцюжок прототипу. Прототипом для об’єкта `user` є `User.prototype`, і він також не має властивості `constructor` (тому що ми "забули" призначити його правильним чином!).
3. Йдучи далі по ланцюжку прототипу, визначаємо, що `User.prototype` є простий об’єкт, його прототипом є вбудований глобальний `Object.prototype`.
4. Врешті, для вбудованого `Object.prototype`, є вбудований конструктор глобального об’єкта `Object.prototype.constructor == Object` от він і використовується.

Таким чином, в кінці, ми отримуємо `let user2 = new Object('Pete')`.
Таким чином, в кінці кінців, ми отримуємо те ж саме, якби написали `let user2 = new Object('Данило')`.

Ймовірно, це не те, що нам потрібно. Ми би хотіли стоврити `new User`, а не `new Object`. Це і є наслідки пропуску властивості `constructor`.

(на випадок, якщо вас зацікавить, виклик `new Object(...)` перетворює його аргументи на об’єкт. Це в теорії, але на практиці ніхто не викликає `new Object` з аргументами; і загалом, не використовується узагалі `new Object` для створення нових об’єктів).
(на випадок, якщо вас зацікавить, виклик `new Object(...)` перетворює його аргументи на об’єкт. Це в теорії, але на практиці ніхто не викликає `new Object` з аргументами; і загалом, `new Object` майже не використовують для створення нових об’єктів).
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ importance: 5
let obj2 = new obj.constructor();
```

Покажіть приклад функції-конструктора для обєкта `obj`, який забезпечить правильну роботу такого коду, а також приклад, який, при такому коді, працює неправельно.
Покажіть приклад функції-конструктора для обєкта `obj`, який забезпечить правильну роботу такого коду, а також приклад, який, при такому коді, працює неправильно.
Loading