views:

301

answers:

6

I had to write a routine that increments the value of a variable by 1 if it is a number, or assigns 0 to the variable if it is not a number. The variable can be incremented by the expression, or be assigned null. No other write access to the variable is allowed. So, the variable can be in three states: it is 0, a positive integer, or null.

My first implementation was: v >= 0 ? v += 1 : v = 0

(Yes, I admit that v === null ? v = 0 : v += 1 is the exact solution, but I wanted to be concise then.)

It failed since null >= 0 is true. I was confused, since if a value is not a number, an numeric expression involving it must be false always. Then I found that null is like 0, since null >= 0 && null <= 0 is true, null < 0 || null > 0 is false, null + 1 == 1, 1 / null == Infinity, Math.pow(2.718281828, null) == 1, ...

Strangely enough, however, null == 0 is evaluated to false. I guess null is the only value that makes the following expression false: (v == 0) === (v >= 0 && v <= 0)

So why null is so special in JavaScript?

+5  A: 

null means no values whreas 0 is value itself.

Salil
That's not precise enough to answer the question.
Tim Down
+3  A: 

null literally means nothing, the variable has no value at all where as 0 is a number, it is a value unlike null. Now because they are not same, null == 0 should be false naturally.

null            ==             0  // false
 ^                             ^
nothing/no value        a number/a value
Sarfraz
lemonedo
@lemonedo: Again becaues `null` is not a value, your comparison is wrong.
Sarfraz
My comparison might be wrong, my Google Chrome JavaScript Console says it is `true`.
lemonedo
Actually, `null` [is a value](http://bclary.com/2004/11/07/#a-4.3.11), what is happening is type coercion to number.
CMS
It also says that `null < 0 || null > 0` is false...
lemonedo
@CMS: That's useful, it is actually a non-existent/empty reference.
Sarfraz
A: 

Two ways to check if a value is 0 or null are:

1) The obvious if (val==null || val==0)

2) The more concise if (!val)

nico
A: 

null is the absence of a value. 0 is a value.

LucaB
A: 

alert(typeof null)

Weston C
+11  A: 

Your real question seem to be:

Why:

null >= 0; // true

But:

null == 0; // false

What really happens is that the Greater-than-or-equal Operator (>=), performs type coercion (ToPrimitive), with a hint type of Number, actually all the relational operators have this behavior.

You can see the inner details of this process in the The Abstract Relational Comparison Algorithm.

Edit: In response to your comment:

That's because null is treated in a special way by the Equals Operator (==).

In a brief, it only coerces to undefined:

null == null; // true
null == undefined; // true

All other values you mention are subject to numeric type coercion, all of them coerce to zero.

You can see the inner details of this process in the The Abstract Equality Comparison Algorithm.

CMS
+1: That's useful link.
Sarfraz
I've just got one more question: all other zero-like values (`false`, `''` (empty string), `'0'`, `[]`) satisfies `x == 0` but why `null` does not?
lemonedo
in the same document 11.9.3 The Abstract Equality Comparison Algorithm.1. If Type(x) is different from Type(y), go to step 14. And after 14 step we go down to the 22.(Return false) because other steps are not corresponding to our statement.
chapluck