JS
function constructor
Привязка контекста
Потеря this.
Мы уже видели примеры потери this. Как только метод передаётся отдельно от объекта – this теряется.
let user = {
firstName: "Вася",
sayHi() {
console.log(`Привет, ${this.firstName}!`);
}
};
setTimeout(user.sayHi, 1000); // Привет, undefined!
Метод setTimeout в браузере имеет особенность: он устанавливает this=window для вызова функции
Task
Исправьте код
let user = {
firstName: "Вася",
sayHi() {
console.log(`Привет, ${this.firstName}!`);
}
};
setTimeout(user.sayHi, 1000); // Привет, undefined!
Решение: Функция обертка
let user = {
firstName: "Вася",
sayHi() {
console.log(`Привет, ${this.firstName}!`);
}
};
setTimeout(function() {
user.sayHi(); // Привет, Вася!
}, 1000);
Привязка контекста
Функция обертка
let user = {
firstName: "Вася",
sayHi() {
console.log(`Привет, ${this.firstName}!`);
}
};
setTimeout(() => user.sayHi(), 1000); // Привет, Вася!
Привязка контекста
Функция обертка
let user = {
firstName: "Вася",
sayHi() {
console.log(`Привет, ${this.firstName}!`);
}
};
setTimeout(() => user.sayHi(), 1000);
// ...в течение 1 секунды
user = { sayHi() { alert("Другой пользователь в 'setTimeout'!"); } };
// Другой пользователь в 'setTimeout'!
Привязка контекста
В современном JavaScript у функций есть встроенный метод bind, который позволяет зафиксировать this.
let user = {
firstName: "Вася"
};
function getName() {
console.log(this.firstName);
}
let funcUser = getName.bind(user);
funcUser(); // Вася
bind
Здесь func.bind(user) – это «связанный вариант» func, с фиксированным this=user.
Сделайте так что бы при вызове метода sayHi вывелось имя Vic при помощи привязки контекста.
function sayHi() {
console.log( this.name );
}
Task
Вызов checkPasswork() в приведённом ниже коде должен проверить пароль и затем вызвать user.loginOk/loginFail в зависимости от ответа.
Однако, его вызов приводит к ошибке. Почему?
function checkPassword(ok, fail) {
let password = prompt("Password?", '');
if (password === "javascript") ok();
else fail();
}
let user = {
name: 'Вася',
loginOk() {
console.log(`${this.name} logged in`);
},
loginFail() {
console.log(`${this.name} failed to log in`);
},
};
checkPassword(user.loginOk, user.loginFail);
Task
function showFullName() {
console.log( this.firstName + " " + this.lastName );
}
let user = {
firstName: "Василий",
lastName: "Петров"
};
// функция вызовется с this=user
showFullName.call(user) // "Василий Петров"
call
Вызов func.call(context, a, b...) – то же, что обычный вызов func(a, b...), но с явно указанным this(=context).
func.call(context, arg1, arg2);
// идентичен вызову
func.apply(context, [arg1, arg2]);
apply
Вызов функции при помощи func.apply работает аналогично func.call, но принимает массив аргументов вместо списка.
function Animal(name) {
this.name = name;
this.canWalk = true;
}
let dog = new Animal("dog");
console.log(dog.name)
Function Constructor
Функции-конструкторы являются обычными функциями. Но есть два соглашения:
- Имя функции-конструктора должно начинаться с большой буквы.
- Функция-конструктор должна вызываться при помощи оператора "new".
Function Constructor
Когда функция вызывается как new Animal(...), происходит следующее:
- Создаётся новый пустой объект, и он присваивается this.
- Выполняется код функции. Обычно он модифицирует this, добавляет туда новые свойства.
- Возвращается значение this.
Другими словами, вызов new Animal(...) делает примерно вот что:
function Animal(name) {
// 1. this = {}; (неявно)
// 2. добавляет свойства к this
this.name = name;
this.canWalk = true;
// 3. return this; (неявно)
}
let dog = new Animal("dog");
console.log(dog)
Function Constructor
{
name: "dog",
canWalk: true,
}
function Animal(name) {
// this = {}; (неявно)
// добавляет свойства к this
this.name = name;
this.canWalk = true;
// return this; (неявно)
}
let dog = new Animal("dog");
console.log(dog.name)
Function Constructor
Function Constructor
Возврат значения
Обычно конструкторы ничего не возвращают явно. Их задача – записать все необходимое в this, который в итоге станет результатом.
Но если return всё же есть, то применяется простое правило:
- При вызове return с объектом, будет возвращён объект, а не this.
- При вызове return с примитивным значением, примитивное значение будет отброшено.
Другими словами, return с объектом возвращает объект, в любом другом случае конструктор вернёт this.
Function Constructor
Создание методов
function User(name) {
this.name = name;
this.sayHi = function() {
alert( "Меня зовут: " + this.name );
};
}
let vasya = new User("Вася");
vasya.sayHi(); // Меня зовут: Вася
/*
vasya = {
name: "Вася",
sayHi: function() { ... }
}
*/
Function Constructor
- Функции-конструкторы или просто конструкторы являются обычными функциями, именовать которые следует с заглавной буквы.
- Конструкторы следует вызывать при помощи оператора new. Такой вызов создаёт пустой this в начале выполнения и возвращает заполненный в конце.
Мы можем использовать конструкторы для создания множества похожих объектов.
Task
Реализуйте функцию конструктор, которая при создании будет принимать два аргумента. Данная функция должна предоставлять два метода sum и multiply. При вызове этих методов должны использоваться данные которые были переданы при создании обьекта.
JS
By Oleg Rovenskyi
JS
function constructor
- 286