问题
I have this code:
(function() {
var ex;
try {
throw new Error('blah');
} catch(ex) {
console.log('ex i here:', ex);
}
console.log('ex out here:', ex);
return 'hi';
})()
This logs:
ex i here: Error('blah');
ex out here: undefined
Why is this so? I would think due to hoisting, ex
would get set outside of this block scope, so it should be available in ex out here
.
I expected it to work similar to a for loop:
for (i=0; i<2; i++) {
}
console.log(i); // gives 2
回答1:
You are messing few things up.
Variables that are defined as var
have function-scope. The parameter in catch
is not hoisted, it has block-scope (only in that catch part).
As you can see in this example: The ab
is hoisted and then is accessible outside the catch part. The ex2
does not exist outside the context.
(function() {
var ex;
try {
throw new Error('blah');
} catch(ex2) {
var ab = 3;
console.log('ex is here:', ex2.message);
}
console.log(ab);
console.log(ex2);
console.log('ex out here:', ex);
return 'hi';
})()
In your example, there is different variable created with the same name, but different scope. If this happens, then (in almost all languages) the "deepest" variable in your context is used. If you want to take the error outside of catch with hositing, you can:
(function() {
try {
throw new Error('blah');
} catch(ex2) {
var ex = ex2;
console.log('ex is here:', ex2.message);
}
console.log(ex.message);
return 'hi';
})()
回答2:
This code behaves like this
(function() {
var ex1;
try {
throw new Error('blah');
} catch(ex2) {
console.log('ex i here:', ex2);
}
console.log('ex out here:', ex1);
return 'hi';
})()
That is because the second the ex declared in the catch is only visible to the catch's scope, for more information visit
Regarding the loop, in those iterations, js looks for the variable "i" declaration of the closest scope that contains it, which in this case is the parent, so the variable "i" that is changing is the one declared at the beggining as there is no variable declaration inside de loop.
回答3:
From try ... catch statement:
When an exception is thrown in the
try
block,exception_var
(e.g., thee
incatch (e)
) holds the value specified by thethrow
statement. You can use this identifier to get information about the exception that was thrown. This identifier is local to thecatch
clause. That is, it is created when thecatch
clause is entered, and after thecatch
clause finishes executing, the identifier is no longer available.
来源:https://stackoverflow.com/questions/55402456/no-hoisting-in-catch-statement