«Единственный способ творить великие дела – это любить то, что ты делаешь»
JavaScript


Игра на «Морской Бой» на JavaScript: Простая Игра и Игра для Двоих


Далее на странице...



Контекст вызова функции прописывается как 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

Результат в Браузере

При этом мы увидим undefined.

Итог №1: обычная функция this = window, если use strict, то undefined.

Замыкание функции

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? Ответ undefined.

Даже если функция используется внутри другой функции, то this либо ссылается на объект Window, либо возвращает undefined.

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

Здесь мы видим 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 - одно свойство this.name с каким-то значением name;

this.id = id - другое свойство this.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 и «какое-то» name.

Создается объект user со свойством name.

Как получить доступ к свойству name объекта 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*num или в данном случае 2*3.

Всегда можно изменить this здесь: const double = count.bind(2), то есть передать через метода bind в функцию count (а вернее уже в новую функцию double) любое значение this.

А при вызове функции double(num) указать любое значение аргумента num.

Здесь были рассмотрены 4 варианта работы с функциям, когда меняется контекст.

Как можно использовать это на практике? Далее будем работать с обработчиками событий.



Читайте также...



Отзывы и комментарии:

Комментариев нет...

Оставить отзыв:

Ваше Имя:

Текст комментария:

Ответьте на вопрос:

Сколько дней в Високосном году?


Рунет - Часть 5
Помощь сайту
Yandex-деньги/Ю-Money
410011236419322
Перевод на карту СБ
4276 1300 1671 5819
WebMoney
R711879515665 Z861169301432

Тематические публикации
Популярные заметки
Последние заметки