JavaScript: What is the difference between `if (!x)` and `if (x == null)`?
What is the difference between if (!x)
and if (x == nul开发者_如何学Gol)
; that is, when can their results be different?
!x
will return true
for every "falsy" value (empty string, 0
, null
, false
, undefined
, NaN
) whereas x == null
will only return true
if x
is null
(edit: or apparently undefined
(see below)).
Try with x = 0
, there is a difference.
You can say that the NOT operator !
converts a value into its opposite boolean equivalent. This is different than actually comparing two values.
In addition, if you compare values with ==
, JavaScript does type conversion which can lead to unexpected behavior (like undefined == null
). It is better to always use strict comparison ===
(value and type must be the same) and make use of type conversion only if you really know what you are doing.
Something to read:
- Data Type Conversion
- Comparison Operators
- Logical Operators
Update:
For more information about the non-strict comparison of null
and undefined
(or the comparison in general), it is worth having a look at the specification. The comparison algorithm is defined there (the comparison is x == y
):
- If Type(x) is the same as Type(y), then
(...)- If x is null and y is undefined, return true.
- If x is undefined and y is null, return true.
- (...)
(...)
The results can be different if x is false, NaN, '' (empty string), undefined (using the strict comparison operator ===), or 0 (zero).
See Felix Kling's answer for an excellent summary of type comparison.
if (!x)
coerces x uses the internal ToBoolean function
if (x==null)
coerces both operands using the internal ToPrimitive function (which generally resolves each side to a number, occasionally a string, depending on the operands)
For full explanantion of ToBoolean vs ToPrimitive see http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/
Say x is a string.
x = undefined;
if(!x) {
alert("X is not a truthy value");
}
if(x == null) {
alert("X is null");
}
x = "";
if(!x) {
alert("X is not a truthy value");
}
if(x == null) {
alert("X is null");
}
x = null;
if(!x) {
alert("X is not a truthy value");
}
if(x == null) {
alert("X is null");
}
You'll notice that "X is not a truthy value" is shown in all three cases, but only in the case of X being undefined or null is "X is null" shown.
When X is a boolean value, then (!x)
will be true when X is false but (x == null)
will not be. For numbers 0 and NaN are considered false values, so not X is truthy.
See it in action, including the difference between ==
(equality using type conversion) and ===
(strict equality)
!x
tests for a false value. This will be true for any value that can propagate to false for whatever reason. This will be true for permutations of false
, 0
, etc etc.
x == null
is different because var x = 0
will NOT be null... but WILL be false.
精彩评论