var f = function() {
this.x = 5;
(function() {
this.x = 3;
})();
console.log(this.x);
};
f.call(f);
f();
f.call();
var f = function() {
this.x = 5;
(function() {
this.x = 3;
})();
console.log(this.x);
};
f.call(f);
f();
f.call();
Во первых вы вызываете функцию. И внутри этой функции функция сама т.е. 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
Если нет определенного контекста, 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
);
Я бы порекомендовал пройти через это с помощью отладчика, если это еще не ясно.
Когда вы вызываете 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("---------------")
В дополнение к другим ответам, если вы хотите предсказуемое поведение, у вас есть по крайней мере 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
Ключевое слово this ссылается на объект контекста, в котором выполняется текущий код. Вне любой функции это относится к глобальному объекту.
Используя функции call()
, apply()
значение этого может передаваться из одного контекста в другой контекст.
this.x
первый аргумент как f
, this.x
ссылается на 5. Таким образом, ответ печатается как 5.this
, как 3. Таким образом, он печатает как 3.3
в качестве вывода.