Why is there a `null` value in JavaScript?
Solution 1
The question isn't really "why is there a null value in JS" - there is a null value of some sort in most languages and it is generally considered very useful.
The question is, "why is there an undefined value in JS". Major places where it is used:
- when you declare
var x;
but don't assign to it,x
holds undefined; - when your function gets fewer arguments than it declares;
- when you access a non-existent object property.
null
would certainly have worked just as well for (1) and (2)*. (3) should really throw an exception straight away, and the fact that it doesn't, instead of returning this weird undefined
that will fail later, is a big source of debugging difficulty.
*: you could also argue that (2) should throw an exception, but then you'd have to provide a better, more explicit mechanism for default/variable arguments.
However JavaScript didn't originally have exceptions, or any way to ask an object if it had a member under a certain name - the only way was (and sometimes still is) to access the member and see what you get. Given that null
already had a purpose and you might well want to set a member to it, a different out-of-band value was required. So we have undefined
, it's problematic as you point out, and it's another great JavaScript 'feature' we'll never be able to get rid of.
I actually use undefined when I want to unset the values of properties no longer in use but which I don't want to delete. Should I use null instead?
Yes. Keep undefined
as a special value for signaling when other languages might throw an exception instead.
null
is generally better, except on some IE DOM interfaces where setting something to null
can give you an error. Often in this case setting to the empty string tends to work.
Solution 2
Best described here, but in summary:
undefined is the lack of a type and value, and null is the lack of a value.
Furthermore, if you're doing simple '==' comparisons, you're right, they come out the same. But try ===, which compares both type and value, and you'll notice the difference.
Solution 3
I don't think there's any reason to have both null
and undefined
, because the only reason many people have suggested ("undefined
means there's no such variable/property") is not valid, at least in JavaScript. undefined
can't tell you whether the variable/property exists or not.
console.log(foo); // "ReferenceError: foo is not defined"
// foo does not exist
var foo;
console.log(foo); // "undefined", a different response
console.log(foo === undefined); // "true", but it does exist
var obj = {};
console.log(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.log(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.log(obj.foo === undefined); // "true", but it does exist
obj.bar = "delete me";
obj.bar = undefined;
console.log(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.log(obj.hasOwnProperty("bar")); // "false", deleted
As you can see, checking foo === undefined
does not tell you whether foo
exists, and setting obj.bar = undefined
does not actually delete bar
.
It may be the JavaScript author's original intent that undefined
should represent "nonexistence". However, the implementation didn't turn out that way.
Solution 4
It is entirely possible to need both. For instance if you query WMI it is entirely possible to have a class return properties that have a null value. They are defined, they just happen to hold null at the time.
Solution 5
I think that your conclusion that JavaScript defines undefined
as "there is no such property" and null
as "the property has no value" is perfectly correct. And in a language as dynamic as JavaScript it is a very important distinction. The use of duck typing means that we need to be able to differentiate between a property not existing and not having a value. It is our primary means of deriving type information. in a statically typed language there is a definite distinction between a field being null and a field not existing. In JavaScript this is no different. However it is checked at runtime, and can be modified up until that time.
I'm going to have to agree that the implementation is strange as a lot of time the distinction is blurred. However I think that in JavaScript the distinction is important. And being able to assign undefined
is essential.
I remember reading a blog post a while ago about an online RPG written in JavaScript. It used examples where objects were created as copies of existing instances rather than prototypes (classes, functions, whatever), and were then altered. This really made me understand how powerful that undefined
could be when modifying existing objects, but I cannot remember who wrote it.
Christoph
Updated on May 18, 2020Comments
-
Christoph about 4 years
In JavaScript, there are two values which basically say 'I don't exist' -
undefined
andnull
.A property to which a programmer has not assigned anything will be
undefined
, but in order for a property to becomenull
,null
must be explicitly assigned to it.I once thought that there was a need for
null
becauseundefined
is a primitive value andnull
an object. It's not, even iftypeof null
will yield'object'
: Actually, both are primitive values - which means neitherundefined
nornull
can be returned from a constructor function, as both will be converted to an empty object (one has to throw an error to proclaim failure in constructors).They also both evaluate to
false
in boolean contexts. The only real difference I can think of is that one evaluates toNaN
, the other to0
in numeric contexts.So why is there both
undefined
andnull
if this just confuses programmers who are incorrectly checking fornull
when trying to find out whether a property has been set or not?What I'd like to know is if anyone has a reasonable example where it's necessary to use
null
which couldn't be expressed usingundefined
instead.So the general consensus seems to be that
undefined
means 'there is no such property' whilenull
means 'the property does exist, but holds no value'.I could live with that if JavaScript implementations would actually enforce this behavior - but
undefined
is a perfectly valid primitive value, so it can easily be assigned to existing properties to break this contract. Therefore, if you want to make sure if a property exists, you have to use thein
operator orhasOwnProperty()
anyway. So once again: what's the practical use for separate values forundefined
andnull
?I actually use
undefined
when I want to unset the values of properties no longer in use but which I don't want todelete
. Should I usenull
instead? -
Christoph over 15 yearsI know that
null !== undefined
- my question was why there was a need for two things which express the same semantic concept; also, your link mentions that 'null is an object' - that's wrong, it's a primitive... -
Christoph over 15 yearsbut you can use
undefined
just fine to assign to properties, so this contract (only returnundfined
if there's no such property) can easily be broken by the programmer... -
Daniel Schaffer over 15 yearsThey aren't the same semantic concept. To me at least, there is a significant difference between a property being assigned a null value, and a property not existing.
-
StefanTflch over 15 yearsBut that's just it, they're not the same semantic concept. Null gets coerced when using == into implying the same thing, as a convenience to the programmer.
-
Kev over 15 yearsAnd in prototypes I think, is a member null or just undefined.
-
Christoph over 15 yearsbut this only works as long as no one tries to break it - if I set
obj.userid = undefined
, it'll fail - see the last edit to my question -
Christoph over 15 yearsand this is relevant to my question in what way?
-
rfunduk over 15 yearsYou can, but you most definitely should not. Undefined is used as a very basic/simplistic form of exception in JavaScript - don't use it as a value and assign it to some property! That's crazy man.
-
rfunduk over 15 yearsIt's relevant because it answers your question. 'null' is a 'singleton' of sorts that means 'has no value'. 'undefined' is telling you that something is... shocking, I know... not defined. They're completely different things.
-
Eric Elliott about 11 years@Christoph
typeof null === 'object';
-
Christoph about 11 years@EricElliott:
typeof
lies - read the spec or try returningnull
from a constructor -
Eric Elliott about 11 years@Christoph Of course you're right, but that "try returning null from a constructor" comment is a confusing counterpoint to your argument: It will return an object. Returning any falsey value from a constructor will result in the constructor returning
this
, instead. -
Eric Elliott about 11 yearsReplace
undefined
withnull
in your above code examples, and the responses are all the same. I'm not sure how this answers the question. Was this meant as a comment on somebody else's answer? -
Christoph about 11 years@EricElliott: the return value of constructors has nothing to do with falsy-ness, but with object-ness: if the return value is an object, return that; if it's a primitive like
null
or42
, discard the return value and return the newly created object instead -
Eric Elliott about 11 years@Christoph How could I forget that? Thanks for the correction. =)
-
Lei Zhao about 11 years@EricElliott My answer to the question is that there's no reason to have both
null
andundefined
, because the only reason many people have suggested is not valid. -
Eric Elliott about 11 yearsYou should edit your answer and actually say that. I might have upvoted if you had given that answer. =)
-
Eric Elliott about 11 yearsThis example is contrived and a bit nonsensical. Null does not clarify your intent at all -- rather, it masks it. You could have used a more explicit string in to clarify the meaning. Like, 'withhold' or 'strip' and then you could also get more explicit about the function type and actually check for the presence of a function.
-
Lei Zhao about 11 years@EricElliott I think you are right. I have edited my answer. Thanks!
-
Erik Reppen over 10 yearsArgs are expandable. You can drop in as many as you like and a function could potentially iterate through and make use of them all. Objects can be assigned a new property at any time. These are both powerful features but I suspect having exceptions thrown as you'd prefer would be a lot of overhead. IMO, it's worth the tradeoff. I spend a lot less time checking for existance in JS than I typically do casting in stricter language paradigms.
-
martinkunev over 10 yearsnote that executng the first two lines from a file will actually print "undefined" because of hoisting
-
Aleksej Komarov almost 10 yearsThis example actually shows that if you did not assign a variable, it returns
undefined
. But if you did assignundefined
to it, it is not actuallyundefined
- it was defined withundefined
and has reference to it. The only difference betweenundefined
andnull
is their usage and historical purpose. They are both atomic. -
Phillip almost 9 yearsFunny how the accepted answer to a question starts off with "this isn't really the question..."
-
Andy about 8 years@bobince did early versions of JS not have the
in
operator orhasOwnProperty
? Because they are way safer thanobj.hello !== undefined
for checking if a property exists on an object. -
Andy about 8 yearsNevermind, I answered my own question. According to MDN, they were both introduced in ES3.
-
Michael over 4 yearsCould you please share this RPG?
-
chharvey almost 3 yearsAdding to your “Major places where [undefined] is used” list: (4) when a function completes execution but does not explicitly return a value.