Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript local scoping: var vs. this

I can't seem to get my head around a specific case of scoping for JavaScript variables. Different from other examples and questions I have found, I am interested in the scoping for nested functions.

I've set up an example at this JSFiddle. The relevant part is the following:

function MyObject() {
    var self = this;

    var a = 1;
    this.b = 2;

    var innerMethod = function() {
        //1 and 2: direct reference
        logMessage("a = " + a); // a = 1
        //logMessage("b = " + b); // Error: b is not defined

        //3 and 4: using this
        logMessage("this.a = " + this.a); // this.a = undefined
        logMessage("this.b = " + this.b); // this.b = undefined

        //5 and 6: using self
        logMessage("self.a = " + self.a); // self.a = undefined
        logMessage("self.b = " + self.b); // self.b = 2
    }
}

Now, I understand that a reference to a directly works. I also understand that messages 3 and 4 (this.a and this.b) will fail because this refers to the internal function. I also understand that line 6 works because I save the reference to the original object.

What I do not understand is:

  • why aren't messages 1 and 2 working alike?
  • why aren't messages 5 and 6 working alike?
like image 376
Alpha Avatar asked Feb 23 '13 23:02

Alpha


People also ask

Is VAR local scoped?

Variables declared with the var keyword are always function-scoped, meaning they recognize functions as having a separate scope. This locally-scoped variable is therefore not accessible from the global scope.

Is VAR local or global?

Any variable declared with the var keyword inside a function is a local variable.

What are the three types of scopes in JavaScript?

JavaScript has 3 types of scope: Block scope. Function scope. Global scope.

What are the two types of scopes in JavaScript?

JavaScript has the following kinds of scopes: Global scope: The default scope for all code running in script mode. Module scope: The scope for code running in module mode.


2 Answers

The a variable is just that, a variable. It's visible in the scope of innerMethod (which is just a nested function), as a, which is how it was declared (ie. JavaScript has lexical scoping rules, inner functions can see variables of the functions they're defined inside of).

this isn't the same as the local scope of the MyObject constructor.

You've seen that self is an alias for this of MyObject, and that innerMethod has overwritten this in its own scope. Still, since this is not an alias for function scope, neither self.a nor this.a will ever work here.

For a more rigorous explanation of lexical scoping you can e.g. start at wikipedia: http://en.wikipedia.org/wiki/Scope_(computer_science)

You can read about the execution contexts and identifier resolution rules in the ECMA standard http://es5.github.com/#x10.3

like image 85
thebjorn Avatar answered Sep 19 '22 15:09

thebjorn


It's a problem with scope, when functions are created they save their surroundings (including variables).

So when innerMethod is created, it can see variables self and a.

An important concept is that the scope is created when the function is declared, instead of when it is called.

In your case 1, b is not being declared (the this object is not the same).

In cases 5 and 6, you did not create self.a.

like image 38
Kaeros Avatar answered Sep 20 '22 15:09

Kaeros