Вопросы на собеседовании фронтенд-разработчика. Объекты и this в JS
Объекты
Объекты в JS — коллекции пар «ключ/значение», являются общими структурными элементами.
К значениям можно обращаться через . + propName или ["propName"]. При каждом обращении движок вызывает внутренние операции
[[Put]] и [[Get]].
Могут быть в 2-х формах:
{} // декларативной (литеральной)
new Object() // сконструированнойСвойства объекта обладают характеристиками:
- writable
- configurable
- enumerable
ими можно управлять при помощи дескрипторов свойств.
Геттеры и сеттеры
Свойства не обязательно содержат значения — они могут быть свойствами доступа с геттерами и сеттерами.
Дескрипторы функции доступа:
get (геттеры) — свойства, которые вызывают функцию для получения нужного значения.
set (сеттеры) — свойства, которые вызывают функцию для присваивания значения.
Shadowing (замещение)
Shadowing — когда свойство текущего объекта замещает любое свойство с тем же названием находящееся выше по цепочке [[Prototype]].
Для замещения существует 3 кейса:
-
Если выше по цепочке
[[Prototype]]находится свойство с тем же названием и оно не помечено какwritable: false, то новое свойство добавляется в текущий объект, т.е. замещает его -
Аналогично первому кейсу, только значение
writable=false. В этом случае установить значение через оператор=не получится, только черезObject.defineProperty() -
Если выше по цепочке добавляемое свойство имеет сеттер, то всегда будет вызываться сеттер.
В итоге к замещению с помощью оператора = приводит только первый кейс. В остальных случаях нужно использовать Object.defineProperty().
Что такое this
this — ключевое слово, которое обозначает специальный идентификатор. Этот идентификатор автоматически определяется в области видимости каждой функции.
При вызове функции создается запись активации, также называемая контекстом выполнения (Function Execution Context). Запись содержит информацию о том, откуда была вызвана функция (стек вызовов), как она была вызвана, какие параметры были переданы при вызове и т.д. Одним из свойств записи является ссылка this, которая используется на протяжении выполнения этой функции.
this не является ссылкой на саму функцию и не является ссылкой на лексическую область видимости функции.
Связывание this не имеет никакого отношения к тому, где была объявлена функция, но полностью определяется способом вызова этой функции.
Связывание this по умолчанию
Связывание по умолчанию срабатывает когда к функции не применяются никакие дополнительные правила вызова. Для связывания this будет использоваться глобальный объект. Если используется строгий режим, то глобальный объект использоваться не может.
const a = 'hi';
function foo() {
console.log(this.a)
}
foo(); // undefinedПри 'use strict' будет выведено
TypeError: Cannot read properties of undefined (reading 'a'). Без строгого режимаundefined.
Неявное связывание this
Когда при обращении к функции указывается контекстный объект, правило неявного связывания требует, чтобы этот объект использовался для связывания this данного вызова функции.
function foo() {
console.log(this.a);
}
const obj = {
a: 'Hi',
foo: foo,
};
obj.foo(); // HiДля вызова важен только последний уровень цепочки ссылок на свойства объекта, т.е. для obj1.obj2.foo() владельцем будет obj2.
Явное и жесткое связывание this
Явное связывание срабатывает когда используются call(...) и apply(...).
Жесткое связывание — использование функции bind.
Стрелочные функции и this
Стрелочные функции используют для связывания this лексическую область видимости, т.е. наследуют значение this от внешнего вызова функции.
Ключевое слово new и this
Если функция вызывается с new, то this содержит новый сконструированный объект. Имеет наивысший приоритет.