Search code examples
javascriptscopeslexical-scope

Why doesn't the variable stay when I am using the setTimeout method?


var obj = {
    id: 1,
    getId: function(){
        console.log(this.id)
    }
}

obj.getId(); // 1

setTimeout(obj.getId, 1000); // undefined

So I am trying to understand that calling the method directly is doing well but when I call it using the setTimeout method, the scope somehow disappears. Why is that? Is that a flaw in the language or is there something else going on behind the scenes that I don't understand entirely.

I even tried var self = this; in the getId method but it still would say self.id is undefined. What is going on?

PS: I am using node v6.5.0 to run this code through.


Solution

  • You are losing the ThisBinding (the value of this inside of a function) when passing the function reference that way.

    Instead, pass obj.getId.bind(obj).

    setTimeout(obj.getId.bind(obj), 1000); 
    

    Think about it like there is a bunch of functions in memory, and if you call one with obj.getId(), you're telling it to pass obj as its ThisBinding.

    However, if you pass simply obj.getId, you are simply giving it a function reference to some function, and it doesn't know which object it should use as the context (so it will default to the global object). Using Function.prototype.bind() can lock-down the ThisBinding to your choosing.