#javascript #scope #this #settimeout
#javascript #область видимости #это #время установки
Вопрос:
Я знаю, что this
ключевое слово всегда ссылается на this
текущую область, которая меняется каждый раз, когда вы что-то function() { ... }
вводите. Мой вопрос в том, почему у меня есть доступ к переменной внешней области x
видимости в функции внутри setTimeout
функции?
var x = 45;
function getRecipe(recipe) {
x = 35;
return {
displayRecipe: function(a) {
//here we have access to x=35
setTimeout(function() {
//why do we have access to x=35 and to recipe here?
console.log(this.x a recipe);
}, 1500)
}
}
}
getRecipe("noodles").displayRecipe(2);
Ответ №1:
Когда не в строгом режиме и когда this
вызов не установлен, this
внутренние функции по умолчанию будут иметь значение глобального объекта ( window
в браузерах).
function f1() {
return this;
}
console.log(f1() === window); // true
Также в браузерах, когда они не находятся в строгом режиме, глобальные переменные (переменные, объявленные в глобальной области видимости), объявленные с var
помощью, также создаются как члены глобального объекта.
var foo = "foobar";
console.log(foo === window.foo);
Поскольку ваша x
объявлена как глобальная переменная, она также добавляется как член window
объекта. Поскольку ваш setTimeout
обратный вызов явно не устанавливает область this
видимости, он также по умолчанию использует глобальный объект, и поэтому возможно, что вы можете получить доступ x
через this
.
Если x
бы она не была объявлена в глобальной области видимости (или была бы объявлена в строгом режиме или с let
const
помощью оператора / ), вы не смогли бы получить к ней доступ:
(function() {
var x = 45;
function getRecipe(recipe) {
x = 35;
return {
displayRecipe: function(a) {
//here we have access to x=35
setTimeout(function() {
//why do we have access to x=35 and to recipe here?
console.log(this.x, a, recipe);
}, 1500)
}
}
}
getRecipe("noodles").displayRecipe(2);
})();
Комментарии:
1. итак, x = 35 объявлено в глобальной области видимости?
2.
var x = 45;
объявлена в глобальной области видимости и, следовательно, является глобальной переменной. Вы меняете значение этой глобальной переменной на35
значение внутри вашейgetRecipe
функции. (Но изменение значения не изменяет область действия переменной.)
Ответ №2:
Вы должны поставить let перед x=35
var x=45;
function getRecipe(recipe){
let x=35;
return{
displayRecipe: function(a){
//here we have access to x=35
setTimeout(function(){
//why do we have access to x=35 and to recipe here?
console.log(this.x a recipe );
},1500)
}
}
}
getRecipe("noodles").displayRecipe(2);