В обычном нестрогом браузерном script без глобальных firstName/lastName вывод: Bill, undefined, Boris, Bill, undefined, Boris, undefined. В strict mode последовательность прервётся раньше.
Что выведет консоль при вызове методов объекта в JavaScript
В обычном нестрогом браузерном script без глобальных firstName/lastName вывод: Bill, undefined, Boris, Bill, undefined, Boris, undefined. В strict mode последовательность прервётся раньше.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Нужно предсказать, какие значения появятся в консоли после выполнения каждой строки кода ниже. Обратите внимание на различия между обычными функциями и стрелочными, а также на влияние bind и потерю контекста.
var person = {
firstName: 'Bill',
lastName: 'Ivanov',
sayName: function() {
console.log(this.firstName);
},
sayLastName: () => {
console.log(this.lastName);
}
};
person.sayName(); // ?
var unboundSayName = person.sayName;
unboundSayName(); // ?
person.sayName.bind({ firstName: 'Boris' })(); // ?
person.sayName(); // ?
person.sayLastName(); // ?
person.sayName.bind({ firstName: 'Boris' }).bind({ firstName: 'Tom' })(); // ?
person.sayLastName.bind({ lastName: 'Petrov' })(); // ?
Ответ
В обычном нестрогом браузерном script без глобальных firstName/lastName вывод: Bill, undefined, Boris, Bill, undefined, Boris, undefined. В strict mode последовательность прервётся раньше.
sayName — обычный метод: this определяется способом вызова. unboundSayName теряет объект; в strict mode this=undefined и второе обращение бросает TypeError, так что последующие строки без try/catch не выполняются.
bind создаёт новую функцию и не меняет исходный метод. Повторный bind уже привязанной функции не заменяет this, поэтому останется Boris, не Tom. sayLastName — стрелка с внешним this; bind на него не влияет. В ES-модуле внешний this=undefined, поэтому и отдельный вызов стрелки завершился бы ошибкой. Наличие глобальных одноимённых свойств меняет нестрогий результат.