Прототипы, наследование Flashcards
Что такое протипное наследование ?
Возможность языка реализовать это
Например, у нас есть объект user со своими свойствами и методами, и мы хотим создать объекты admin и guest как его слегка изменённые варианты. Мы хотели бы повторно использовать то, что есть у объекта user, не копировать/переопределять его методы, а просто создать новый объект на его основе.
Какие есть способы задать прототип ?
- rabbit.__proto__ = animal;
2.let rabbit = {
jumps: true,
__proto__: animal
};
3.Object.getPrototypeOf/Object.setPrototypeOf
Какие ограничения существуют у прототипа ?
Есть только два ограничения:
Ссылки не могут идти по кругу. JavaScript выдаст ошибку, если мы попытаемся назначить __proto__ по кругу.
Значение __proto__ может быть объектом или null. Другие типы игнорируются.
Чем является Свойство __proto__ для [[Prototype]] ?
Обратите внимание, что __proto__ — не то же самое, что внутреннее свойство [[Prototype]]. Это геттер/сеттер для [[Prototype]].
Какую важную особенность нужно помнить про прототип ? Какое исключение из этой особенности ?
Прототип используется только для чтения свойств.
Операции записи/удаления работают напрямую с объектом.
Свойства-аксессоры – исключение, так как запись в него обрабатывается функцией-сеттером. То есть это фактически вызов функции.
Как итерироваться(for in ) только по не унаследованным свойствам объекта ? Почему не будет этого метода при итерации ?
Если унаследованные свойства нам не нужны, то мы можем отфильтровать их при помощи встроенного метода obj.hasOwnProperty(key): он возвращает true, если у obj есть собственное, не унаследованное, свойство с именем key.
…Но почему hasOwnProperty не появляется в цикле for..in в отличие от eats и jumps? Он ведь перечисляет все унаследованные свойства.
Ответ простой: оно не перечислимо. То есть у него внутренний флаг enumerable стоит false, как и у других свойств Object.prototype. Поэтому оно и не появляется в цикле.
На что будет ссылаться this если метод взят из прототипа ?
Если мы вызываем obj.method(), а метод при этом взят из прототипа, то this всё равно ссылается на obj. Таким образом, методы всегда работают с текущим объектом, даже если они наследуются.
Пусть есть функция-конструктора new F(). Чем является F.prototype для F
F.prototype означает обычное свойство с именем “prototype” для F.Это ещё не «прототип объекта», а обычное свойство F с таким именем.
Объясните когда F.prototype становится прототипом ? Изменится ли унаследованный от прототипа объект при изменении свойств прототипа ?
F.prototype используется только при вызове new F() и присваивается в качестве свойства [[Prototype]] нового объекта. После этого F.prototype и новый объект ничего не связывает. Следует понимать это как «единоразовый подарок» объекту.
После создания F.prototype может измениться, и новые объекты, созданные с помощью new F(), будут иметь другой объект в качестве [[Prototype]], но уже существующие объекты сохранят старый.
Какой свойство есть у каждой функции по умолчанию ? Что находится в этом свойстве ?
Для чего может быть удобно это свойство ?
По умолчанию “prototype” – объект с единственным свойством constructor, которое ссылается на функцию-конструктор.
Мы можем использовать свойство constructor существующего объекта для создания нового.
function Rabbit(name) {
this.name = name;
alert(name);
}
let rabbit = new Rabbit(“White Rabbit”);
let rabbit2 = new rabbit.constructor(“Black Rabbit”);
Что самое важное в свойстве конструктор ?
…JavaScript сам по себе не гарантирует правильное значение свойства “constructor”.
Чем должно быть значение F.prototype ?
Значение F.prototype должно быть либо объектом, либо null. Другие значения не будут работать.
Что такое [[Prototype]] ?
скрытое свойство [[Prototype]] (так оно названо в спецификации), которое либо равно null, либо ссылается на другой объект. Этот объект называется «прототип»:
Что выведет этот код ?
function Rabbit() {}
Rabbit.prototype = {
eats: true
};
let rabbit = new Rabbit();
delete rabbit.eats;
alert( rabbit.eats ); // ?
Во что преобразуют new Object аргумент ?
На всякий случай, если вам интересно, вызов new Object(…) преобразует свой аргумент в объект.