17

According to What is the difference between null and undefined in JavaScript?, null and undefined are two different objects (having different types) in Javascript. But when I try this code

var a=null;
var b;
alert(a==null);      // expecting true
alert(a==undefined); // expecting false
alert(b==null);      // expecting false
alert(b==undefined); // expecting true

The output of the above code is:

true
true
true 
true

Now as == only matches the value, I thought that both undefined and null must have the same value. So I tried:

alert(null) -> gives null

alert(undefined) -> gives undefined

I don't understand how is this possible.

Here is the demo.

Edit

I understand that === will give the expected result because undefined and null have different types, but how does type conversion work in Javascript in the case of ==? Can we do explicit type conversion like we do in Java? I would like to apply a manual type conversion on undefined and null.

RJFalconer
  • 10,890
  • 5
  • 51
  • 66
Ankur
  • 12,676
  • 7
  • 37
  • 67
  • What way do you want to convert them? Both to null? – Jon Hanna Aug 31 '12 at 15:49
  • ya either undefined to object(type of null) or `null` to `undefined` – Ankur Aug 31 '12 at 15:51
  • `myVal = myVal == null ? null : myVal;` should do the trick. Now it's definitely not undefined. – Jon Hanna Aug 31 '12 at 16:10
  • @JonHanna i was expecting some thing more like `(typeof(undefined))(null)`, the above is more like an if and else based on the predicat that `null==undefined` – Ankur Aug 31 '12 at 16:16
  • That's exactly what it is. And no, it isn't nice. – Jon Hanna Aug 31 '12 at 16:21
  • null is an object `typeof(null) == "object"`. undefined is something that is not defined. all you can do with undefined is, see if a variable is declared or not. nothing more. – Prasanth Sep 09 '12 at 09:29

7 Answers7

19

You need to use the identity operator ===, not the equality operator ==. With this change, your code works as expected:

alert(a===null);      // true
alert(a===undefined); // false
alert(b===null);      // false
alert(b===undefined); // true

The reason the equality operator fails in this case is because it attempts to do a type conversion. undefined is of type undefined, and null is of type object; in attempting to compare the two, Javascript converts both to false, which is why it ends up considering them equal. On the other hand, the identity operator doesn't do a type conversion, and requires the types to be equal to conclude equality.

Edit Thanks to @user1600680 for pointing out, the above isn't quite correct; the ECMAScript specification defines the null-to-undefined as special case, and equal. There's no intermediate conversion to false.


A simpler example of type conversion is number-to-string:
console.log(5 == "5");    // true
console.log(5 === "5");   // false

The above answer has a good quote from Douglas Crockford's Javascript: The Good Parts:

[The "==" operator does] the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. the rules by which they do that are complicated and unmemorable.

If you don't believe that the rules are complicated and unmemorable, a quick look at those rules will disabuse you of that notion.

Community
  • 1
  • 1
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • 6
    While I agree that your answer is essentially valid, it probably wouldn't hurt to explain why this behavior is exhibited in Javascript ;) – Adam Eberlin Aug 31 '12 at 15:35
  • i understand this, but what i don't understand is why do `==` always give true wven though alerting both null and undefined give different output – Ankur Aug 31 '12 at 15:36
  • The differance it that the type is also compaired and not just the value. 2=="2" is true but not 2==="2" – rekire Aug 31 '12 at 15:36
  • hi, are the rules documented somewhere, can you please provide a link and also is there a way for explicit type conversion in JS? – Ankur Aug 31 '12 at 15:44
  • you actually didn't answer the question. – jAndy Aug 31 '12 at 15:45
  • thanks you so much, `in attempting to compare the two, Javascript converts both to false, which is why it ends up considering them equal` cleared everything. – Ankur Aug 31 '12 at 15:50
  • 1
    The "complicated and unmemorable" rules that the linked page summarises (the exact rules in ECMA 262 are worse again) are the sort of thing you can end up with when you start with "let's just make it simple and do the obvious thing". Being simple, can be very complicated. – Jon Hanna Aug 31 '12 at 15:54
  • 1
    This answer isn't right. The `null` and `undefined` values are not converted to `false`. The `==` conversion rules are *very simple* when it comes to these values. The `null` and `undefined` values will equal nothing except `null` and `undefined`. No further conversion is needed. – gray state is coming Aug 31 '12 at 16:00
  • ...also the "type" of `null` is not object when doing the comparison. You're thinking of the `typeof` operator, which isn't used internally. – gray state is coming Aug 31 '12 at 16:03
  • @user1600680 `The null and undefined values will equal nothing except null and undefined. No further conversion is needed.`, then how are they equal when `==` is used??? if `null` is `null` and `undefined` is `undefined`? – Ankur Aug 31 '12 at 16:05
  • 2
    as I said, `null` and `undefined` will equal nothing except `null` and `undefined`. As in `null` equals `null`, `null` equals `undefined`, `undefined` equals `null`, `undefined` equals `undefined`. But `null` or `undefined` equals `[any other value]` will be false. – gray state is coming Aug 31 '12 at 16:07
  • 1
    http://es5.github.com/#x11.9.3 `2. If x is null and y is undefined, return true. 3. If x is undefined and y is null, return true.` There's no other coercion happening. The `==` in general does not convert to a Boolean value. It has a specific algorithm that more often converts to a Number. – gray state is coming Aug 31 '12 at 16:10
  • @user1600680 thanks for the link, can you add it as an answer so that i can except it, thanks for the documented link :) – Ankur Aug 31 '12 at 16:12
  • @user1600680 So basically you're saying `null` and `undefined`, while having different types, are considered equivalent for the purposes of type conversion. Thanks for the clarification; I'll fix the errors in my answer. – McGarnagle Aug 31 '12 at 16:12
  • 1
    @dbaseman: Exactly. :) While it seems odd, the algorithm rarely coerces to a boolean like `false`. If it did, then `true == "0"` would be `true` because `Boolean(true) == Boolean("0")` becomes `true` == `true`. In reality, it is more likely to coerce to a Number. Using the previous example: `Number(true) == Number("0")` we get the same result as `true == "0"`, because the `==` is ultimately coercing both to a Number. So `true` becomes `1` and `"0"` becomes `0`, which are unequal. But yes, `null` and `undefined` are a special case that avoids the more complicated coercion algorithm. – gray state is coming Aug 31 '12 at 19:31
5

undefined and null have very different semantic meanings.

undefined typically means "There wasn't any reply" and null means "There was a reply and that reply was nothing."

For instance, if I created this object:

var gameState = {
  state: loaded,
  lastPlayer: null,
  lastScore: null
};

This doesn't mean "I don't know who the last player was" rather it means "there wasn't a last player."

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
  • I understand this, but essentially my question is what type of algo is applied when using `==` for `null` and `undefined`, how are they compared? what is the type conversion, what does that type conversion return? – Ankur Aug 31 '12 at 16:08
  • thanks for the link, it cleared everything, it has already been added to the ans http://stackoverflow.com/a/12218504/662250 – Ankur Aug 31 '12 at 16:19
2

To clarify a previous answer, the reason why == works this way is because, unlike ===, it does type conversion

Community
  • 1
  • 1
DVK
  • 126,886
  • 32
  • 213
  • 327
2
 var a;
 var b = null;

a is undefined, b is completely null.

== is used to compare for equality in a deliberately loose way, that is often useful

alert("3" == 3.0);

That gives us true though they're clearly different - one's a number and one a string.

A lot of the time though, this is great.

Likewise, a lot of the time don't care if something has no real value because it was undefined, or because it was explicitly set to null.

While useful sometimes, we do also sometimes need to know the exact type matches as well as the value, so we have === too.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
2

I will like to also say that the undefined is used with the typeof. The compare must be as:

if( typeof(b)=="undefined" ){}

that gives the same results as

if( b === undefined ){}

and I have include this extra tests on your code http://jsfiddle.net/A89Qj/5/

Aristos
  • 66,005
  • 16
  • 114
  • 150
1

You need to use === instead of ==. The === operator behaves the same way as the == operator except it does not do any type conversion.

ewein
  • 2,695
  • 6
  • 36
  • 54
0

typeof undefined is undefined but type of null is object. null === undefined will give you false. but null == undefined will give you true. as boh are of different data type but have same value.