I’m trying to wrap my head around the behavior of reference errors thrown in JavaScript.
In the following example, a ReferenceError
is thrown at the second line, and execution breaks:
var obj = {};
obj.func1 = func2;
alert('Completed');
Whereas in this example, the code completes successfully, though obj.func1
remains undefined
:
var obj = {};
obj.func1 = func2;
var func2 = function() {
alert('func2');
};
alert('Completed');
My assumption was that an error would be thrown at the second line just the same, and when that wasn’t the case, I’d have expected obj.func1
to properly reference func2
, but I’ve been double blind-sided. So what exactly is going on here?
var
is hoisted; the variable exists throughout the current scope. Thus, the second example is equivalent to:
var obj;
var func2;
obj = {};
obj.func1 = func2;
func2 = function() {
alert('func2');
}
alert('Completed');
Thus, when you do the assignment, The name func2
is known, but undefined
. In the first example, it is unknown, which raises ReferenceError
.
This is due to Javascript variable declaration "hoisting".
A variable declared with var
is visible everywhere in the function, so there's no Reference Error
. However, it doesn't actually receive its value until you execute the statement that initializes it. So your second example is equivalent to:
var func2;
var obj = {};
obj.func1 = func2;
func2 = function() {
alert('func2');
};
alert('Completed');
In this rewrite, you can see that the variable exists when you perform the assignment to obj.func1
. But since it doesn't yet have a value, you assign undefined
to obj.func1
. Assigning to func2
later doesn't change that.
Your func2 variable is not visible. That's why obj.func1 remains undefined.
var obj = {};
var func2 = function() {
alert('func2');
return "Test";
};
obj.func1 = func2;
alert('Completed');
来源:https://stackoverflow.com/questions/35473439/why-is-no-referenceerror-being-thrown-if-a-variable-is-used-before-it-s-declared