Далее на странице...
- Простой вызов функции Обычная функция this = window, если use strict, то undefined
- Замыкание функции Замыкание функции
- Вызов метода объекта this - контекст у методов объекта - сам объект.
- Оператор new - Функции конструкторы this в конструкторах и классах - это новый экземпляр объекта
- Методы call, apply и bind Ручное присвоение this любой функции Методы call и apply - Разница Метод bind создает новую функцию
Контекст вызова функции прописывается как this. Если говорить по-простому, то это то, что окружает функцию и в каких условиях она вызывается.
Функция может вызываться несколькими способами. А если учесть 'use strict' то существует больше вариантов контекста вызова функции.
Простой вызов функции
1-ый способ вызова функции.
Контекст вызова this - Простой вызов функции.
В этом случае this может вести себя по-разному.
JavaScript-код
//'use strict';
function showThis() {
console.log(this);
};
showThis();
Результат в консоли
Window
Результат в Браузере
Если функция запускается таким вот образом и в ней используется контекст this, то этот контекст будет ссылаться на объект Window.
Это правило верно для обычного кода без строгого режима 'use strict'.
Контекст вызова this - строгий режим use strict
JavaScript-код
'use strict';
function showThis() {
console.log(this);
};
showThis();
Результат в консоли
undefined
Результат в Браузере
При этом мы увидим
.Итог №1: обычная функция this = , если use strict, то .
Замыкание функции
JavaScript-код
'use strict';
function showThis(a, b) {
console.log(this);
function sum() {
console.log(this);
return this.a + this.b;
}
console.log(sum());
};
showThis(2, 7);
Результат в Браузере
1. Какой контекст вызова у функции sum? Ответ .
Даже если функция используется внутри другой функции, то this либо ссылается на объект Window, либо возвращает .
2. Что вернет функция sum()? Ответ - ошибку.
Результат в консоли
undefined
undefined
Uncaugh TypeError: Cannot read properties of undefined (reading 'a')
.
.
Чтобы функция sum() вернула сумму аргументов - нужно убрать this из выражения return this.a + this.b;
JavaScript-код
'use strict';
function showThis(a, b) {
console.log(this);
function sum() {
console.log(this);
return a + b;
}
console.log(sum());
};
showThis(2, 7);
Результат в Браузере
Результат в консоли
undefined
undefined
9
Таким образом, используется замыкание функции: для функции sum() не указаны аргументы, но в ее теле указано return a + b.
Замыкание функции: если функция не находит аргументы у себя, то она берет их из родительской функции.
Вызов метода объекта
2-ой способ вызова функции.
Контекст вызова this - Вызов метода объекта.
Известно, что методы объекта - это тоже функции. Для примера рассмотрим объект, у которого есть свойства и методы.
JavaScript-код
'use strict';
const obj = {
a: 15,
b: 20,
sum: function() {
console.log(this);
}
};
obj.sum(); // вызов метода объекта
Результат в Браузере
В консоли мы получили объект, в котором находится метод sum().
Какой контекст вызова у этой функции?
Здесь можно сформулировать важный постулат.
Если используется метод внутри объекта, то контекст this будет всегда ссылаться на этот объект.
Итог №2: Контекст у методов объекта - .
Внутренняя функция метода объекта
Какой контекст вызова у внутренней функции метода объекта?JavaScript-код
'use strict';
const obj = {
a: 15,
b: 20,
sum: function() {
function shout() {
console.log(this);
}
shout();
}
};
obj.sum();
Результат в Браузере
Результат в консоли
undefined
Здесь мы видим не относящийся к объекту (это не метод объекта). Функция запускается внутри метода объекта.
. Почему? Потому что это уже простой вызов функции,Оператор new - Функции конструкторы
3-ой способ вызова функции.
Третий способ использования и вызова функций - через оператор new. Это функции конструкторы: пример рассматривался здесь.
JavaScript-код
function User(name, id) {
this.name = name;
this.id = id;
this.human = true;
};
let ivan = new User('Ivan', 28);
Когда функция конструктор вызывается let ivan = new User('Ivan', 28) - создается новый объект.
Что видно из примера?
this.name = name - одно свойство с каким-то значением name;
this.id = id - другое свойство с каким-то значением id.
Прежде чем записать указать свойство, прописывается this - т.е. каждый раз происходит обращение к какому-то объекту.
Итак, внутри функции конструктора контекст вызова для всех методов и свойств - это вновь созданный объект.
let ivan = new User('Ivan', 28) - создается объект ivan.
Таким образом, this ссылается на экземпляр объекта, в данном случае на ivan созданный в этот строке: new User('Ivan', 28).
Итак, когда создается новый объект, то в this передается именно он.
Итог №3: this в конструкторах и классах - это новый экземпляр объекта.
Методы call, apply и bind
Ручное присвоение this любой функции
4 способ, когда меняется контекст вызова функции
Ручное присвоение this любой функции при помощи методов call, apply и bind.
JavaScript-код
'use strict';
function sayName() {
console.log(this);
console.log(this.name);
}
const user = {
name: "John"
};
sayName.call(user);
sayName.apply(user);
Результат в Браузере
Результат в консоли
{name: 'John'}
John
{name: 'John'}
John
Создается функция: выводится в консоль просто this и «какое-то» .
Создается объект user со свойством .
Как получить доступ к свойству user из функции sayName?
объектаДля этого используются методы call и apply. В примере выше они имеют одинаковый синтаксис.
Итак, благодаря методам call и apply можно получить доступ к методам объекта из функции.
Методы call и apply - Разница
Из примера выше НЕ видно: есть ли разница между методами call и apply.
Она есть и заключается в синтаксисе. Но при дополнительных условиях.
JavaScript-код
'use strict';
function sayName(surName) {
console.log(this);
console.log(this.name + surName);
}
const user = {
name: "John"
};
sayName.call(user, 'Smith');
sayName.apply(user, ['Smith']);
Результат в Браузере
Результат в консоли
Object
JohnSmith
Object
JohnSmith
Из примера можно увидеть разницу между методами call и apply.
Функция sayName имеет аргумент surName.
В синтаксисе метода call аргумент (его значение) передается через запятую.
В синтаксисе метода apply аргументы передаются через массив.
Метод bind
Третий метод ручного присвоения контекста this - метод bind.
Метод bind
, связанную с определенным контекстом.В примерах с методами call и apply новая функция НЕ создавалась, а только устанавливался контекст.
JavaScript-код
'use strict';
function count(num) {
return this*num;
}
const double = count.bind(2);
console.log(double(3));
console.log(double(6.5));
Результат в Браузере
Результат в консоли
6
13
1) Есть функция count с аргументом num, которая умножает контекст this на num.
2) переменную double, в которую помещаем : для этого обращаемся к существующей функции с использованием метода bind. Таким образом, double - это новая функция.
const double = count.bind(2)
Здесь 2 переходит в this, а num передается в double.
3) Итак, double(3) - возвращает this* или в данном случае 2* .
Всегда можно изменить this здесь: const double = count.bind(2), то есть передать через метода bind в функцию count (а вернее уже в новую функцию double) любое значение this.
А при вызове функции double(num) указать любое значение аргумента num.
Здесь были рассмотрены 4 варианта работы с функциям, когда меняется контекст.
Как можно использовать это на практике? Далее будем работать с обработчиками событий.