setTimeout 中定义的函数可以访问 JavaScript 中的外部变量

Function defined in setTimeout has access to the outer variables in JavaScript

我知道 this 关键字总是指当前范围的 this,它会在您将某些内容包装在 function() { ... } 中时发生变化。我的问题是,为什么我可以在 setTimeout 函数内部的函数中访问外部作用域变量 x

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);

你应该把 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);

当不在 strict mode, and when the this is not set by the call, this inside functions will default to the global object (window 浏览器中时)。

function f1() {
  return this;
}

console.log(f1() === window); // true

同样在非严格模式下的浏览器中,用var声明的全局变量(在global scope中声明的变量)也被创建为全局对象的成员。

var foo = "foobar";
console.log(foo === window.foo);

因为你的x被声明为全局变量,所以它也被添加为window对象的成员。因为您的 setTimeout 回调没有显式设置 this 范围,它也默认为全局对象,因此您可以通过 this.[= 访问 x 29=]

如果 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);
})();