views:

1363

answers:

7

In JavaScript, there are two values which basically say 'I don't exist' - undefined and null.

A property to which a programmer has not assigned anything will be undefined, but in order for a property to become null, null must be explicitly assigned to it.

I once thought that there was a need for null because undefined is a primitive value and null an object. It's not, even if typeof null will yield 'object': Actually, both are primitive values - which means neither undefined nor null can be returned from a constructor function, as both will be converter 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 to NaN, the other to 0 in numeric contexts.

So why is there both undefined and null if this just confuses programmers who are incorrectly checking for null when trying to find out whether a property has been set or not?

edit: What I'd like to know is if anyone has a reaosonable example where it's necessary to use null which couldn't be expressed using undefined instead.

edit2+3: So the general consensus seems to be that undefined means 'there is no such property' while null means 'the property does exist, but holds no value'.

I could live with that if JavaScript implementations would actually enforce this behaviour - 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 the in operator or hasOwnProperty() anyway. So once again: what's the practical use for seperate values for undefined and null?

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?

+3  A: 

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.

EBGreen
+17  A: 

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.

Eddie Parker
I 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
They 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.
Daniel Schaffer
But 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.
Eddie Parker
+1  A: 

Semantically they mean different things. The type null has exactly one value in its domain, null and a property may be assigned this specific value. Undefined represents a distinct lack of any value having been assigned.

AnthonyWJones
but you can use `undefined` just fine to assign to properties, so this contract (only return `undfined` if there's no such property) can easily be broken by the programmer...
Christoph
You _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.
thenduks
+1  A: 

Try this example:

<html>
<head>
    <script type="text/javascript">
        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "\n");
            }

            alert(propCollection);
        }

        var obj = {
            userid: 3,
            name: 'me!',
            speak: function() { alert('Hi! My name is ' + this.name + ' and my ID is ' + this.userid + '.'); }
        }

        //Shows all properties
        ShowObjProperties(obj);

        //The Speak function is no longer in the list!
        delete obj.speak;
        alert(typeof obj.speak);
        ShowObjProperties(obj);

        //The UserID is still listed, it just has no value!
        obj.userid = null;
        ShowObjProperties(obj);
    </script>
</head>
<body>

</body>
</html>

I think that there is a very real use for 2 different types here.

EndangeredMassa
And in prototypes I think, is a member null or just undefined.
Kev
but 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
+1  A: 

What it comes down to is javascripts dynamic nature.

Things may be undefined so that they can be added at a later point. This is arguably why javascript is so powerful and extensible.

Rob Stevenson-Leggett
and this is relevant to my question in what way?
Christoph
It'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.
thenduks
+2  A: 

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.

Im 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.

Jack Ryan
+6  A: 

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:

  1. when you declare 'var x;' but don't assign to it, x holds undefined;
  2. when your function gets fewer arguments than it declares;
  3. 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 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 signalling 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.

bobince