You do not know JS «This и Прототипы Объектов», Flashcards
Что такое this ?
В действительности this — это привязка, которая создается во время вызова функции, и на что она ссылается определяется тем, где и при каких условиях функция была вызвана.
Когда функция вызывается, создается запись активации, также известная как контекст вызова. Эта запись содержит информацию о том, откуда функция была вызвана (стэк вызова), как функция была вызвана, какие параметры были в неё переданы и т.д. Одним из свойств этой записи является ссылка this, которая будет использоваться на протяжении выполнения этой функции.
Какие правила определение this (по приоритетам) ?
Теперь можно кратко сформулировать правила для определения this по точке вызова функции, в порядке их приоритета. Зададим вопросы в том же порядке и остановимся как только будет применено первое же правило.
Функция вызвана с new (привязка new)? Раз так, то this — новый сконструированный объект.
var bar = new foo()
Функция вызвана с call или apply (явная привязка), даже скрыто внутри жесткой привязки в bind? Раз так, this — явно указанный объект.
var bar = foo.call( obj2 )
Функция вызвана с контекстом (неявная привязка), иначе называемым как владеющий или содержащий объект? Раз так, this является тем самым объектом контекста.
var bar = obj1.foo()
В противном случае, будет this по умолчанию (привязка по умолчанию). В режиме strict mode, это будет undefined, иначе будет объект global.
var bar = foo()
Рассажите как определяется this в этом коде ?
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2
Однако, точка вызова использует контекст obj, чтобы ссылаться на функцию, поэтому можно сказать, что объект obj “владеет” или “содержит” ссылку на функцию в момент вызова функции.
Какое название вы бы ни выбрали для этого шаблона, в момент когда вызывается foo(), ей предшествует объектная ссылка на obj. Когда есть объект контекста для ссылки на функцию, правило неявной привязки говорит о том, что именно этот объект и следует использовать для привязки this к вызову функции.
Поскольку obj является this для вызова foo(), this.a — синоним obj.a.
Только верхний/последний уровень ссылки на свойство объекта в цепочке имеет значение для точки вызова. Например:
function foo() {
console.log( this.a );
}
var obj2 = {
a: 42,
foo: foo
};
var obj1 = {
a: 2,
obj2: obj2
};
obj1.obj2.foo(); // 42
Как раньше реализовался спред синтаксис для передачи параметров в функцию с помощью чего он достигался ?
Если вы передаете null или undefined в качестве параметра привязки this в call, apply или bind, то эти значения фактически игнорируются, а взамен к вызову применяется правило привязки по умолчанию.
Довольно распространено использовать apply(..) для распаковки массива значений в качестве параметров вызова функции. Аналогично и bind(..) может каррировать параметры (предварительно заданные значения), что может быть очень полезно.
function foo(a,b) {
console.log( “a:” + a + “, b:” + b );
}
// распакуем массив как параметры
foo.apply( null, [2, 3] ); // a:2, b:3
// каррируем с помощью bind(..)
var bar = foo.bind( null, 2 );
bar( 3 ); // a:2, b:3
Обa этих инструмента требуют указания привязки this в качестве первого параметра. Если рассматриваемым функциям не важен this, то вам нужно -значение-заменитель, и null — это похоже разумный выбор, как мы видели выше.
Как создать объект без объектного прототипа ?
var ø = Object.create( null );
Какой самый распространенный вариант использования стрелочных функций ?
Самый распространенный вариант использования стрелочной функции — обычно при использовании функций обратного вызова, таких как обработчики событий или таймеры:
Стрелочные функции по существу являются синтаксической заменой …… ?
self = this
function foo() {
var self = this; // лексический захват this
setTimeout( function(){
console.log( self.a );
}, 100 );
}
var obj = {
a: 2
};
foo.call( obj ); // 2
Можно ли изменить свойство значение дескриптора свойства с false на true ?
В общем случае - нет.
Примечание: существует особенное исключение, о котором стоит помнить: если для свойства уже задано configurable:false, то writable может быть изменено с true на false без ошибки, но не обратно в true если оно уже false.
Что выведет этот код ?
В чем отличие от запроса неинициализированной переменной
var myObject = {
a: 2
};
myObject.b;
Это поведение отличается от случая, когда вы обращаетесь к переменным по имени их идентификатора. Если вы запросите переменную, которая не может быть найдена с помощью поиска по лексической области видимости, то результатом будет не undefined, как у свойств объекта, а ошибка ReferenceError.
Подробнее про геттеры и сеттеры
Геттеры – это свойства, которые, на самом деле, вызывают скрытую функцию для получения значения. Сеттеры – это свойства, которые, на самом деле, вызывают скрытую функцию для задания значения.
Когда вы задаете свойству геттер или сеттер, оно определяется как «дескриптор доступа» (в противовес «дескриптору данных»). Для дескрипторов доступа, характеристики дескриптора value и writable игнорируются, а вместо этого JS рассматривает характеристики свойства set и get (а также configurable и enumerable).
В чем отличие in от hasOwnProperty ?
Оператор in проверит находится ли свойство в объекте или существует ли оно уровнем выше в цепочке [[Prototype]] объекта (смотрите Главу 5). hasOwnProperty(..) наоборот проверяет есть ли свойство только у объекта myObject или нет и не опрашивает цепочку [[Prototype]]. Мы еще вернёмся к важным различиям между этими двумя операциями в Главе 5, когда исследуем [[Prototype]] более подробно.