Прототипы, наследование 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(…) преобразует свой аргумент в объект.
Какие значения имеют и не имеют объектов-оберток ?
Значения null и undefined не имеют объектов-обёрток
создан временный объект-обёртка с использованием встроенных конструкторов String, Number и Boolean, который предоставит методы и после этого исчезнет.
Эти объекты создаются невидимо для нас, и большая часть движков оптимизирует этот процесс, но спецификация описывает это именно таким образом. Методы этих объектов также находятся в прототипах, доступных как String.prototype, Number.prototype и Boolean.prototype.
Что такое полифил ?
Полифил – это термин, который означает эмуляцию метода, который существует в спецификации JavaScript, но ещё не поддерживается текущим движком JavaScript.
Когда одобряется изменение встроенных прототипов ? Почему почти всегда это не одобряется ?
В современном программировании есть только один случай, в котором одобряется изменение встроенных прототипов. Это создание полифилов.
Прототипы глобальны, поэтому очень легко могут возникнуть конфликты. Если две библиотеки добавляют метод String.prototype.show, то одна из них перепишет метод другой.
Так что, в общем, изменение встроенных прототипов считается плохой идеей.