I noticed an interesting result from JSLint while researching a codereview question. JSLint complained that a variable was used before it was defined. Here is a shortened version of code that produces the same result:
(function () {
try {
var a = 0;
throw { name: "fakeError" };
} catch (e) {
a = 1;
}
}());
My understanding of JavaScript says that the above code should be equivalent to:
(function () {
var a;
try {
a = 0;
throw { name: "fakeError" };
} catch (e) {
a = 1;
}
}());
and indeed, neither example causes a
to exist in the global scope when run through Firebug. I took a look at section 12.14 of the ECMA-262 spec, but I don't see anything that would lead me to think the functions should be treated differently. Is this just a bug in JSLint, or are the two expressions different in some functional way?
var is the keyword that tells JavaScript you're declaring a variable. x is the name of that variable.
The scope of a variable declared with var is its current execution context and closures thereof, which is either the enclosing function and functions declared within it, or, for variables declared outside any function, global.
The Var Keyword This means that if a variable is defined in a loop or in an if statement it can be accessed outside the block and accidentally redefined leading to a buggy program. As a general rule, you should avoid using the var keyword.
let allows you to declare variables that are limited to the scope of a block statement, or expression on which it is used, unlike the var keyword, which declares a variable globally, or locally to an entire function regardless of block scope.
It's just a bug, but JSLint's default options would prefer it if you moved all your var statements to the top anyway.
While enclosing some block of code in curly braces {...}
merely doesn't create a new scope in javascript, catch
is an exception as noted in ECMAScript 5 spec. The code inside catch block has a different scope in comparison to the code outside. its treated like functions inner scope.
In other words, as noted here:
The catch block is unique in that JavaScript creates this identifier when the catch block is entered and it adds it to the current scope; the identifier lasts only for the duration of the catch block; after the catch block finishes executing, the identifier is no longer available.
function f() {
try {
throw "foo";
} catch (e) {
}
// e undefined here
}
And as you know, one cannot expect variable hoisting from 2 different scopes of code in javascript. So, JSLint complains because he/she ;-) knows this.
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