4

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

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

2 Comments

so x=35 is declared in the global scope?
var x = 45; is declared in the global scope and thus a global variable. You change the value of this global variable to 35 inside your getRecipe function. (But changing the value does not change the scope of the variable.)
0

You should put let before 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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.