| > Now, sometimes it will throw. No, typeof /isn't/ throwing. let x = 1;
function some_random_function(y) { }
(function() {
some_random_function(x);
let x = 2;
})();
This will throw the same exception for exactly the same reason. You're using a variable defined using "let" before the variable definition. Sod all to do with typeof.I don't see it as massively confusing that a variable declared one way behaves differently to a variable declared another way. That's the whole point of having a new way of declaring a variable. Why isn't everyone up in arms about how confusing it is that it behaves differently here? (function() {
var x = 1;
if (true) {
var x = 10;
}
console.log(x); // Will print 10
})();
(function() {
let x = 1;
if (true) {
let x = 10;
}
console.log(x); // Will print 1
})();
Oh no, if I use "let" it behaves differently to "var"!Its not like its throwing on unexpected data, its throwing because the program isn't constructed properly. This is the same as just about every other language. Are you really saying we shouldn't make improvements to the language because then it would behave differently to the old, poorly designed features we're trying to deprecate? [edit]
You still can use typeof to check if something is defined without throwing on spurious inputs. The only time the code will throw is if you make changes to further down in the lexical scope. And guess what - whether you do that with var or with let you've changed the argument of typeof to refer to a different variable. Except with var it will likely silently fail in a hard to track down way, while with let it will error in an obvious place. let data;
function sanitizeData() {
if (typeof data === 'undefined') {
// data not yet set
return;
}
// sanitize data in place
}
No matter what you put in data, "typeof data" is never going to throw an exception.The only way to get it to throw an exception is to change sanitizeData to add a variable shadowing "data" from the parent scope. let data;
function sanitizeData() {
if (typeof data === 'undefined') {
// data not yet set
return;
}
// sanitize data in place
var data = ...;
// sanitize data in place
}
If I use var, sanitizeData doesn't do anything and I spent a while hunting the issue down. let data;
function sanitizeData() {
if (typeof data === 'undefined') {
// data not yet set
return;
}
// sanitize data in place
let data = ...;
// sanitize data in place
}
If I use let, sanitizeData throws as soon as it's called and I can track down the issue much quicker.The only time "typeof throws an exception" is if you add a let statement later in the lexical scope in a place where if you added a var statement, it would completely change the behaviour of your code in a way you almost certainly didn't want it to. |
The statement `typeof x` still results in a throw. I understand that it's not `typeof` doing it.
It is still the case that before, you could write `typeof x` to see if `x` was defined in all cases, and the line you wrote, `typeof x` would never throw, for any possible state of `x`.
Now, that is no longer true. That is what people are "up in arms" about. Although as far as I know, nobody's actually taken up arms. I hope.
Being picky in an argument about exactly what is throwing does not change this situation. I am not sure what you don't understand, or if you understand everything but you feel that explaining what's really going is supposed to somehow appease people, oh, okay, now that I understand what's going on.... it still doesn't chagne the fact that before, if I wanted to know if `x` is defined, i could write `typeof x !== "undefined"`. In all cases. And the result of that statement would never be a throw. Now, if I want to know if x is defined, there are at least two kinds of "undefined", one that will be returned by `typeof x` as "undefined", and another where I am not allowed to mention `x` at all, including to do `typeof x`.