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:
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.
Any variable declared with the var keyword inside a function is a local variable.
JavaScript has 3 types of scope: Block scope. Function scope. Global scope.
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.
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
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With