If you just want to check whether there's a truthy value, you can do:
if (strValue) {
//do something
}
If you need to check specifically for an empty string over null, I would think checking against ""
is your best bet, using the ===
operator (so that you know that it is, in fact, a string you're comparing against).
if (strValue === "") {
//...
}
Scoping rules
The main difference is scoping rules. Variables declared by var
keyword are scoped to the immediate function body (hence the function scope) while let
variables are scoped to the immediate enclosing block denoted by { }
(hence the block scope).
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar); // Foo Bar
{
var moo = "Mooo"
let baz = "Bazz";
console.log(moo, baz); // Mooo Bazz
}
console.log(moo); // Mooo
console.log(baz); // ReferenceError
}
run();
The reason why let
keyword was introduced to the language was function scope is confusing and was one of the main sources of bugs in JavaScript.
Take a look at this example from another stackoverflow question:
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
My value: 3
was output to console each time funcs[j]();
was invoked since anonymous functions were bound to the same variable.
People had to create immediately invoked functions to capture correct values from the loops but that was also hairy.
Hoisting
While variables declared with var
keyword are hoisted (initialized with undefined
before the code is run) which means they are accessible in their enclosing scope even before they are declared:
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
let
variables are not initialized until their definition is evaluated. Accessing them before the initialization results in a ReferenceError
. The variable is said to be in "temporal dead zone" from the start of the block until the initialization is processed.
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
Creating global object property
At the top level, let
, unlike var
, does not create a property on the global object:
var foo = "Foo"; // globally scoped
let bar = "Bar"; // not allowed to be globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
Redeclaration
In strict mode, var
will let you re-declare the same variable in the same scope while let
raises a SyntaxError.
'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo1' is replaced with 'foo2'.
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
Best Answer
Is the variable
null
:...but note the latter will also be true if
a
isundefined
.Is it
undefined
:...but again, note that the last one is vague; it will also be true if
a
isnull
.Now, despite the above, the usual way to check for those is to use the fact that they're falsey:
This is defined by ToBoolean in the spec.
They're both values usually used to indicate the absence of something.
undefined
is the more generic one, used as the default value of variables until they're assigned some other value, as the value of function arguments that weren't provided when the function was called, and as the value you get when you ask an object for a property it doesn't have. But it can also be explicitly used in all of those situations. (There's a difference between an object not having a property, and having the property with the valueundefined
; there's a difference between calling a function with the valueundefined
for an argument, and leaving that argument off entirely.)null
is slightly more specific thanundefined
: It's a blank object reference. JavaScript is loosely typed, of course, but not all of the things JavaScript interacts with are loosely typed. If an API like the DOM in browsers needs an object reference that's blank, we usenull
, notundefined
. And similarly, the DOM'sgetElementById
operation returns an object reference — either a valid one (if it found the DOM element), ornull
(if it didn't).Interestingly (or not), they're their own types. Which is to say,
null
is the only value in the Null type, andundefined
is the only value in the Undefined type.The only difference between them is that
==
will do type coercion to try to get the values to match, and===
won't. So for instance"1" == 1
is true, because"1"
coerces to1
. But"1" === 1
is false, because the types don't match. ("1" !== 1
is true.) The first (real) step of===
is "Are the types of the operands the same?" and if the answer is "no", the result isfalse
. If the types are the same, it does exactly what==
does.Type coercion uses quite complex rules and can have surprising results (for instance,
"" == 0
is true).More in the spec:
==
, also called "loose" equality)===
)