Okay, I stumbled upon this piece of code..
How come this works? What sort of evil scheme does JavaScript use to resolve variables?
The way I see it, as a C++ kind of guy: the class/object definition contains a non-existent reference to an object of the class being defined. Seriously, how?
(To be honest, I understand partially - I could deduce a strawman concept of how and when JS resolves names.. but maybe this way the question will be of more use to someone else, someday)
Guilty code:
function Sio() {
this.someValue = 5;
this.doStuff = function() {
console.log("look: "+howDoYouResolveThisYouFoulCreature.someValue);
};
}
var howDoYouResolveThisYouFoulCreature = new Sio();
That seems so wrong.
Lots of concepts here, and I'm not sure which one is giving you troubles…
The two most likely ones are new
/ this
and var
.
new
/ this
When you call a function the value of this
is determined by the context in which you call it.
If you use the new
keyword, you create an instance of the function and make that instance the context.
When you call howDoYouResolveThisYouFoulCreature.doStuff()
you are accessing that instance as a global. It would usually make more sense to:
this.doStuff = function() {
console.log("look: "+ this.someValue);
};
Since foo.doStuff()
makes foo
the context for that invokation of doStuff()
(which makes the function reusable between different instances of Sio
)
var
var something
anywhere inside a function will scope that variable to that function var
statement at the top of a function to avoid confusion Also, the doStuff
function is not called before howDoYouResolveThisYouFoulCreature
has a value. Until that point all that matters is that the function is syntactically correct, it doesn't matter what type the variable is.
It works because the function() this.doStuff isn't executed before howDoYouResolveThisYouFoulCreature is created. Keep in mind for as many new Sio()'s that you make this will always console.log the howDoYouResolveThisYouFoulCreature.someValue regardless of the variable name that doStuff() is called from.
This works because:
var howDoYouResolveThisYouFoulCreature = new Sio();
... actually resolves into:
var howDoYouResolveThisYouFoulCreature; howDoYouResolveThisYouFoulCreature = new Sio();
So at the time the function
doStuff
is assigned, the
var
is already declared.
Edit: Forget that, I was being foolish. It turns out pimvdb is right, and here's the proof ( also on jsfiddle ):
function A() { this.logValue = function() { if (b === undefined) { console.log('Wah, wah, wah...'); } else { console.log(b.someValue); } }; } function B() { this.someValue = 42; } var a = new A(); a.logValue(); // Wah, wah, wah... var b = new B(); a.logValue(); // 42
So the execution context is the key. When Sio
(or, in this case, A
) is constructed, it's scoped to where b
might , at some point, be defined. The variable isn't resolved until the function is called, at which point it might be defined. Or not. No biggie. :-)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.