вызов() функции в своем собственном контексте
var f = function() {
this.x = 5;
(function() {
this.x = 3;
})();
console.log(this.x);
};
f.call(f);
f();
f.call();
Ответы
Ответ 1
Первый случай:
Во первых вы вызываете функцию. И внутри этой функции функция сама т.е. f
устанавливается как this
. Итак, в первом примере this.x = 5;
устанавливает свойство x
в функции.
Когда вызывается внутренняя функция, this
относится к объекту window
так что this.x = 3;
изменяет свойство x
объекта окна.
Когда это регистрирует console.log(this.x);
здесь регистрируется то же свойство x
которое было установлено как свойство функции.
Второй случай:
Во втором примере this
внутри внешней функции ссылается на window
поэтому когда this.x = 3;
оценивается window.x
становится 3
. Поскольку this
относится к window
во внешней функции, так console.log(this.x);
logs window.x
который равен 3
Заключение:
Вывод всего обсуждения заключается в том, что если аргумент call()
не передается, то автоматически window
объект window
. По данным МДН
thisArg
Необязательный. Значение этого предусмотрено для вызова функции. Обратите внимание, что это может не быть фактическим значением, видимым методом: если метод является функцией в нестрогом режиме, нулевые и неопределенные будут заменены глобальным объектом, а примитивные значения будут преобразованы в объекты.
Смотрите ниже фрагмент.
function foo(){
console.log(this);
}
foo.call(foo); //foo function
foo.call(); //window object
Ответ 2
Если нет определенного контекста, this
будет window
. Ваша внутренняя функция всегда запускается без контекста, поэтому она установит для window.x
значение 3. Если вы window.x
f()
, она также будет работать с this
существующим window
поэтому записывает 3.
Однако если вы выполните f.call(f)
, this
будет объект функции f
, а для свойства x
будет установлено значение 5.
f.call(f)
console.log(
f.x, // 5
window.x // 3
);
Я бы порекомендовал пройти через это с помощью отладчика, если это еще не ясно.
Ответ 3
Когда вы вызываете f
со ссылкой на себя, она устанавливает для свойства x
значение 5, а внутренняя анонимная функция имеет this
ссылаясь на окно, поэтому она устанавливает значение window.x в 3. За пределами анонимной функции this
прежнему относится в функцию f
, поэтому console.log(this.x) выводит 5.
Когда вы вызываете f с помощью f()
или f.call()
функция f и анонимная функция внутри нее имеют ссылку this
на window
(по умолчанию) и, таким образом, изменяют значение this.x
внутри или вне анонимной функции. влияет на выходной результат.
Вы можете увидеть это ясно, если вы console.log значения this
внутри функции f и внутри внутренней анонимной функции.
var f = function() {
console.log("This inside function f:", this.toString());
this.x = 5;
(function() {
console.log("This inside anonymous inner function:", this.toString());
this.x = 3;
})();
console.log(this.x);
};
console.log("calling function x with this set to itself");
f.call(f);
console.log("---------------")
console.log("invoking function x with brackets ()")
f();
console.log("---------------")
console.log("calling function x without setting this context")
f.call();
console.log("---------------")
Ответ 4
В дополнение к другим ответам, если вы хотите предсказуемое поведение, у вас есть по крайней мере 2 метода, доступных для вас.
Метод 1: (закрытие)
var f = function() {
this.x = 5;
var that = this;
(function() {
that.x = 3;
})();
console.log(this.x);
};
f.call(f); // 3
f(); // 3
f.call(); // 3
Метод 2: (функция стрелки)
var f = () => {
this.x = 5;
(function() {
this.x = 3;
})();
console.log(this.x);
};
f.call(f); // 3
f(); // 3
f.call(); // 3
Ответ 5
Ключевое слово this ссылается на объект контекста, в котором выполняется текущий код. Вне любой функции это относится к глобальному объекту.
Используя функции call()
, apply()
значение этого может передаваться из одного контекста в другой контекст.
- Так, в 1-м случае [ f.call(f) ], вызвав функцию вызова и
this.x
первый аргумент как f
, this.x
ссылается на 5. Таким образом, ответ печатается как 5. - 2-й случай [ f() ] это вызов функции без использования функции вызова. Таким образом, это относится контекст выполнения
this
, как 3. Таким образом, он печатает как 3. - В третьем случае [ f.call() ] внутри функции вызова не упоминается аргумент. Таким образом, он ссылается на глобальный объект и печатает
3
в качестве вывода.