Search code examples
javascriptnode.jsscoping

Bind scoping javascript


I'm trying to figure out scoping of using bind. I'm confused about the output of boundF1. What is going on here?

// console.log(x) ReferenceError: x is not defined

// setting this.x - this here is global or window
this.x = 5;
console.log(x) // 5

function f1() {
  console.log(x); // 5
  console.log(this.x); // 5
}

// Lexically bound this to window 
f2 = () => {
  console.log(x); // 5
  console.log(this.x); // 5
}

f1()
f2()

boundF1 = f1.bind({x:1});
boundF2 = f2.bind({x:1});


boundF1() // 5 1 Why is this not 1, 1. How is x resolved here? Does it check local vars, then global vars. Would it ever use this? What is the scoping rule?

boundF2() // 5 5


Solution

  • When you reference a standalone variable, like console.log(x), the interpreter will try to find a standalone variable with that same name somewhere in the outer scope. Here, the outer scope eventually gets to the global scope, and so console.log(x) resolves to console.log(window.x).

    Properties of this do not get added to a function's variable environment; to reference properties of this, you have to do so explicitly, eg:

    console.log(this.x);
    

    Not that you should ever use it, but there is with, which lets you reference properties of an object as if they were standalone variables (which sounds like what you were thinking would happen automatically), but it's highly not recommended (and forbidden in strict mode).

    this.x = 5;
    
    function f1() {
      with (this) {
        console.log(x); // 5
        console.log(this.x); // 5
      }
    }
    
    boundF1 = f1.bind({x:1});
    
    
    boundF1()