I have a simple if statement
if(variable == null)
does not enter the statement
if(variable == "")
does
Why does this happen??
What is the difference between "" and null in javascript
"" is the empty string. In other words, it's a string of length 0. null on the other hand is more like a generic placeholder object (or an object representing the absence of an object). There's also undefined which is different from both "" and null.
But the point is, "" != null so therefore:
var s = "";
s == null; // false
s == ""; // true
The ECMA–262 Abstract Equality Comparison Algorithm (§ 11.9.3) says that null == null (step 1.b) or null == undefined (steps 2 and 3) return true, everything else returns false.
There are types in JavaScript
typeof("") is "string" and typeof(null) is "object"
"" is a string object with a length of zero. null is the value the represents the absence of a value. A string object is never null, regardless of its length.
As SHiNKiROU mentioned, there are types in Javascript. And since the language is dynamically typed, variables can change type. Therefore, even though your variable may have been pointing to, say, an empty string at some point, it may be changed to point to, say, a number now. So, to check the concept of "nonexistence" or "nothingness" or "undefinededness" of a variable, Crockford recommends against doing stuff like if (variableName == null).
You can take advantage of javascript's dynamically-typed qualities. When you want to check for a variable's "falsiness" or "nothingness", instead of if(variableName == null) (or undefined or "") use if(!variableName)
Also, instead of if(variableName != undefined) (or null or "") use if(variableName)
Related
When I want to make sure a variable x is defined, before using it, I use:
if (typeof x !== "undefined") {
// do stuff with x
}
but I've noticed that others, e.g. in this question, use !== instead of != for the comparison. Which one should I be using, and why?
Note: I realize I can be using !==. The question is whether I should (and whether there will be any difference in behavior).
As noted in a comment by VLAZ, the typeof operator is guaranteed to return a string. If you compare the result to another string, then == and === (or != and !==) will do the exact same thing.
actually, the best approach would be to check if a value is falsy, and based on MDN this is the list of falsy values:
false The keyword false
0 The number zero
0n BigInt, when used as a boolean, follows the same rule as a Number. 0n is falsy.
"", '', ``
This is an empty string (the length of the string is zero). Strings in JavaScript can be defined with double quotes "", single quotes '', or Template literals ``.
null null - the absence of any value
undefined undefined - the primitive value
NaN NaN - not a number
so based on your code what you can do is simply:
if (!x) { // check for all the falsy values.
// do stuff with x
}
in the other hand, you ask for the difference of != and !==, well basically taking some examples you can see the difference:
0 == false // true, because false is equivalent of 0
0 === false // false, because both operands are of different type
2 == "2" // true, auto type coercion, string converted into number
2 === "2" // false, since both operands are not of same type
as mentioned by #VLAZ comment, these cases will only work if the variable x is defined, otherwise you will have the following error:
"Uncaught ReferenceError: x is not defined"
so on your case you could only use != because you will compare string vs string and you will avoid having to check if the variable was or not created.
if (typeof x != "undefined") {
// do stuff with x
}
I want to check this:
if ( typeof myVar != "undefined" && myVar != null )
...
In other words, I want to check if a variable has a defined value (including 0 or an empty string), but not undefined or null, which I interpret as valueless.
Do I have to do the two-part check each time or is there a handy shortcut?
If you want to allow 0 and "" as valid values and you want to cover the case of the variable might not even be delcared, but don't consider null a valid value, then you have to specifically check for undefined and null like this:
if (typeof myVar !== 'undefined' && myVar !== null)
...
A lot of values are falsey (they don't satisfy if (myVar) so you really have to conciously decide which ones you're testing for. All of these are falsey:
undefined
false
0
""
null
NaN
If you want to allow some, but not others, then you have to do a more specific test than if (myVar) like I've shown above to isolate just the values you care about.
Here's a good writeup on falsey values: http://www.sitepoint.com/javascript-truthy-falsy/.
If you know the variable has been declared and you just want to see if it's been initialized with something other than null, you can use this:
if (myVar != undefined)
...
Using only the != instead of !== allows this to test for both undefined and null via type conversion. Although, I wouldn't recommend this because if you're trying to discern between falsey values, it's probably better to NOT let the JS engine do any type conversions at all so you can control exactly what it does without having to memorize all the type conversion equality rules. I'd stick with this to be more explicit:
if (typeof myVar !== 'undefined' && myVar !== null)
...
If you want to know if it has any non-falsey value, you can of course do this (but that won't allow 0 or "" as valid values:
if (myVar)
...
The 2-part method. If you don't check for the typeof first, you'll end up with a reference error.
If you know the context of myVar, you should be able to do this:
if (this.myVar != null) {
...
}
if myvar could be undefined, calling it without the typeof check will throw an error.
And if it is defined as null (like myvar= element.lastChild for an element with no children) you will miss catching it if you just use typeof.
Well, null is a defined value... so if you want to make sure that the variable doesn't contain null, and isn't undefined you must do both checks.
I had an interesting interview question today that stumped me a little. I was asked about falsey values. So undefined, NaN, null, 0, and an empty string all evaluate to false. What is the reason this is useful to know in JavaScript? The only thing I can think of is instead of having to do this:
if (mystring === '' || mystring === undefined) { }
I can do this:
if (!mystring)
Is this the only useful application?
One dangerous issue of falsey values you have to be aware of is when checking the presence of a certain property.
Suppose you want to test for the availability of a new property; when this property can actually have a value of 0 or "", you can't simply check for its availability using
if (!someObject.someProperty)
/* incorrectly assume that someProperty is unavailable */
In this case, you must check for it being really present or not:
if (typeof someObject.someProperty == "undefined")
/* now it's really not available */
Also be aware that NaN isn't equal to anything, even not to itself (NaN != NaN).
There are two separate issues with 'falsey' values in JavaScript.
Firstly there is the official conversion scheme, which is what is returned by Boolean(x). This returns false when x is false or 0 or NaN or null or undefined or "" and true otherwise. This is the same behaviour as the
if (condition) {/*true path*/} else {/*false path*/}
that is, the false path is executed if Boolean(condition) would have returned false and the true path is executed otherwise. This behaviour is often used to check to see if a property is defined. However, doing that is not safe unless you are certain that the property would be an object or an array if it is defined. The safest way to test if a property is defined is to do
if (property != null) { /*property is defined*/}
which makes sure that the property is not null or undefined. If you only want to make sure the property is not undefined do
if (property !== undefined) { /*property is not undefined (but may be null)*/ }
(notice the extra = in !==).
Secondly, there are all the values that == false. This is everything that can be coerced to 0 (which is what false gets coerced to). This includes all the values that convert to false except NaN (which can't == false by virtue of it never == anything), null and undefined. But it also includes all objects that when converted to a string and then converted to a number are equal to 0. For example, this includes everything that when converted to a string is either the empty string "" or "0" or "-0" or "+0" or "0x00" or "000" or "0e0" or "0.0000"...., for example,
({toString: function() {return "-00.0e000";}}) == false
is true. Interestingly, this includes the empty array, and any nesting of arrays containing only a single other item that returns an empty or 0 string since arrays rendered as strings show only the contents without the surrounding brackets. That is,
[[[[0]]]] == false; // Because [[[[0]]]].toString() === "0"
[] == false;
[[[""]]] == false;
["0"] == false;
[[({toString: function() {return "0";}})]] == false;
The full algorithm for calculating == false is described here.
The reason this matters is because it can lead to subtle, difficult to find bugs if you don't understand most of these rules. Most important takeaways are probably how the if (condition) works and that using === avoids most of the other crazy stuff.
It's important to understand how this works in JS, so you're not surprised. Not necessarily just what is falsey, but what is truthy and how they compare to each other.
One example is that '0' is considered equal to 0 with ==, but it is not equal to '' - though 0 is. JavaScript comparison isn't always transitive.
So this means that just because (foo==bar && bar==fizz) is true, (foo==fizz) is not always true. To go with the above example, '0'==0, and 0=='', but '0'!='' - because you're comparing strings in the latter instance, so they are compared as strings and not coerced to numbers.
It is important to know that 0 evaluates to false to prevent doing things like:
if(str.indexOf('foo'))
It's useful to detect if a browser is has specific predefined objects:
if(!!navigator.geolocation){
// executes if the browser has geolocation support
}
if(!!document.createElement('canvas').getContext){
// executes if the browser supports <canvas>
}
Explanation: navigator.geolocation is an object or undefined. In the case it's an object !navigator.geolocation will return false, if it's undefined it'll return true. So, to check if a browser has geolocation enabled, you want to 'flip' the boolean once more, by adding another !.
They're also useful for setting default values...
function foo(bar){
alert(bar || "default");
}
I know a lot of people try to do
if (typeof(foo) === "undefined"){}
to get around falsiness, but that's got its own problems because
typeof(null) === "object"
for some reason
Throughout many third-party libraries and best practices blogs/recommendations, etc... it is common to see syntax like this:
typeof x === 'object' (instead of typeof x == 'object')
typeof y === 'string' (instead of typeof x == 'string')
typeof z === 'function' (instead of typeof x == 'function')
If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.
Under what circumstances will typeof not return a string literal? And even if there's some fringe case why is the additional type check being used for object, string, function, etc...
To answer the main question - there is no danger in using typeof with ==. Below is the reason why you may want to use === anyway.
The recommendation from Crockford is that it's safer to use === in many circumstances, and that if you're going to use it in some circumstances it's better to be consistent and use it for everything.
The thinking is that you can either think about whether to use == or === every time you check for equality, or you can just get into the habit of always writing ===.
There's hardly ever a reason for using == over === - if you're comparing to true or false and you want coercion (for example you want 0 or '' to evaluate to false) then just use if(! empty_str) rather than if(empty_str == false).
To those who don't understand the problems of == outside of the context of typeof, see this, from The Good Parts:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
It's subjective. You can just as easily turn this around, and ask, "Why would you use == when you don't expect implicit conversions?" Both work fine here, so use the one you feel expresses your intention better. Try to be consistent within a project.
There's no reason at all to favour === over == in this case, since both operands are guaranteed to be strings and both operators will therefore give the same result. Since == is one character fewer I would favour that.
Crockford's advice on this is to use === all the time, which is reasonable advice for a beginner but pointlessly paranoid if you know the issues (covered in other answers).
Because === is quicker than ==, due to omitting type coercion.
Sure it is probably a negligible difference but it is still there.
Triple equal operators are mostly used for variable type and value checking (all in 1 expression), also known as equality without type coercion.
Example:
var a = 1;
var b = 1;
var c = "1";
var d = "1";
alert (a === b); //True, same value and same type (numeric)
alert(c === d); //True, same value and same type (string)
alert(b === c); //False, different type but same value of 1
See Doug Crockford's YUI Theater on type coercion.
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
The most efficient reason for not using typeof and rather the === operator would be for type coercion (interpretation) between browsers. Some browsers can pass 6=="6" as true and some wouldn't (depending on the strictness of the JS interpreter) so by introducing type coercion would clarify this.
Also, it would bring the "Object-Orientativity" approach to it since JavasScript's variables are not type-based variables (i.e. variable types are not declared on compile time like in Java).
E.g. in Java, this would fail:
if ("6" instanceof Number) { // false
Hope I answered your question.
I'd like to know the difference (if any) between the following:
if( someDOMElement.someProperty )
{
...
if( someDOMElement.someProperty != null )
{
...
if( someDOMElement.someProperty != undefined )
{
...
Is one safer than the others?
Those will all do the same thing, and one isn't more error-prone than the others. Whereas if you were using !== rather than !=, the second two would only be true if the value really were null (the second one) or undefined (the third one), because the !== operator doesn't do coercion.
Javascript will coerce values during comparisons with != or ==, so for example:
alert(false == 0); // alerts "true"
alert(false === 0); // alerts "false"
The === and !== operators let you control that behavior. The rules for what coercions occur are detailed in the spec (and a bit complicated), but just a simple "is this thing not 0, "", null, or undefined?" can be written simply if (thingy) and it works well. 0, "", null, and undefined are all "falsey".
Sean Kinsey has a point about some host objects, though I think most if not all DOM element properties will be fine. In particular, I've seen COM objects exhibit some interesting behavior, such as if (comObject.property) evaluating true when if (comObject.property == null) also evaluates true. (In my case, it was COM objects exposed as part of the server-side API of a product I was using; I use Javascript server-side as well as client-side.) Worth being aware that that can happen. When you're dealing with Javascript objects and (in my experience) DOM objects, you're fine.
Assuming that someDOMElement is not null, no particular differences:
http://www.steinbit.org/words/programming/comparison-in-javascript
There would be a difference if you use !==
Depending on exactly what someDOMElement is then these can have very different results, and none of them are 'safe' to use if Host Objects are involved (objects implemented as ActiveXObjects for instance).
You should really use a method such as one of these
// use this if you expect a callable property
function isHostMethod(object, property){
var t = typeof object[property];
return t == 'function' ||
(!!(t == 'object' && object[property])) ||
t == 'unknown';
}
// use this if you are only looking for a property
function isHostObject(object, property){
return !!(typeof(object[property]) == 'object' && object[property]);
}
alert(isHostObject(someDOMElement, "someProperty"))
You can read more about proper feature detection at http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
depends on what you call a value.
if(someDOMElement && someDOMElement.someProperty !=undefined){
the property exists and has been set to a value other than undefined or null-
it may be 0, false, NaN or the empty string, as well as any truthy value
}