Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I know that this keyword always refers to the this of the current scope, which changes any time you wrap something in function() { ... }. My question is, why do I have access to the outer scope variable x in the function inside the setTimeout 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);
like image 378
rousspc Avatar asked Sep 16 '25 12:09

rousspc


1 Answers

When not in strict mode, and when the this is not set by the call, this inside functions will default to the global object (window in browsers).

function f1() {
  return this;
}

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

Also in browsers when not in strict mode, global variables (variables declared in the global scope) declared with var are also created as members of the global object.

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

Because your x is declared as a global variable, it is also added as a member of the window object. Because your setTimeout callback does not explicitly set the this scope, it also defaults to the global object, and so it is possible you can access x via this.

If x would not have been declared in the global scope (or would've been declared in strict mode or with a let/const statement), you would not be able to access it:

(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);
})();
like image 180
Ivar Avatar answered Sep 19 '25 01:09

Ivar