Why is there a `null` value in JavaScript?
Asked Answered
H

12

129

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 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 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?

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 using undefined instead.

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 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 the in operator or hasOwnProperty() anyway. So once again: what's the practical use for separate 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?

Hulburt answered 20/1, 2009 at 16:12 Comment(6)
To answer your last question: No, you should not be setting properties to undefined.Cenozoic
"undefined" is just a variable in the global scope with the primitive value "undefined". It is possible to define another value to the variable: { undefined="Hello"; alert(undefined);} A more reliable way to test for undefined: { if (typeof myvar === "undefined") alert("undefined")}Larrisa
See section 4.3.9 - 12 in ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf for undefined/null, and 15.1.1.3 for the variable "undefined" in the global scope.Larrisa
You should either delete an object or set it to null if that makes more sense, but not to undefined.Larrisa
In JavaScript, there are two values which basically say 'I don't exist' - undefined and null. No, only undefined says that.Aude
Possible duplicate of What is the difference between null and undefined in JavaScript?Cranage
R
91

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

Registrant answered 21/1, 2009 at 0:0 Comment(5)
Args 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.Varied
Funny how the accepted answer to a question starts off with "this isn't really the question..."Summarize
@Registrant did early versions of JS not have the in operator or hasOwnProperty? Because they are way safer than obj.hello !== undefined for checking if a property exists on an object.Fellowship
Nevermind, I answered my own question. According to MDN, they were both introduced in ES3.Fellowship
Adding to your “Major places where [undefined] is used” list: (4) when a function completes execution but does not explicitly return a value.Ogrady
I
39

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.

Inhale answered 20/1, 2009 at 16:18 Comment(9)
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...Hulburt
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.Gassing
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.Inhale
@Hulburt typeof null === 'object';Raposa
@EricElliott: typeof lies - read the spec or try returning null from a constructorHulburt
@Hulburt 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.Raposa
@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 or 42, discard the return value and return the newly created object insteadHulburt
@Hulburt How could I forget that? Thanks for the correction. =)Raposa
Just because typeof null=="object" doesn't mean that null is an object. Null is a primitive which is the opposite of an object. typeof null=="object" returns true but it isn't an object. developer.mozilla.org/en-US/docs/Glossary/PrimitiveGlutinous
N
19

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.

Neumann answered 18/10, 2012 at 19:38 Comment(6)
Replace undefined with null 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?Raposa
@EricElliott My answer to the question is that there's no reason to have both null and undefined, because the only reason many people have suggested is not valid.Neumann
You should edit your answer and actually say that. I might have upvoted if you had given that answer. =)Raposa
note that executng the first two lines from a file will actually print "undefined" because of hoistingBarbabra
This example actually shows that if you did not assign a variable, it returns undefined. But if you did assign undefined to it, it is not actually undefined - it was defined with undefined and has reference to it. The only difference between undefined and null is their usage and historical purpose. They are both atomic.Tradition
This should be the accepted answerGlutinous
E
6

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.

Edging answered 20/1, 2009 at 16:17 Comment(0)
H
6

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.

Halm answered 20/1, 2009 at 17:45 Comment(1)
Could you please share this RPG?Burdened
C
3

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.

Canonical answered 20/1, 2009 at 16:21 Comment(2)
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...Hulburt
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.Savoirvivre
O
3

As a Java programmer, I see a huge difference between undefined and null. Coding JavaScript, not so much, because JavaScript is not strongly typed, and the differences between undefined and null are blurred by the automatic conversions that are frequently performed by run-time. BTW, I take frequent advantage of those conversions; they make my JS code more compact and readable.

To answer your question, undefined means that a value was never set. Practically speaking, this generally points to a bug. If yourObject.property is undefined, that means you didn't set the property for some reason, or I'm looking for something that doesn't exist at all. This is a real issue when working on a project with more than one coder.

null means that "no value" was explicitly set. Practically speaking, you are telling me something about the property, perhaps that it isn't used in this context, or that a value has yet to be determined.

In Java, attempts to access a field that is undefined will always result in an exception. In fact, the compiler can be made to warn you about this in your code.

Omar answered 11/4, 2012 at 14:25 Comment(0)
V
0

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.

Vowelize answered 20/1, 2009 at 17:4 Comment(2)
And in prototypes I think, is a member null or just undefined.Catalan
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 questionHulburt
V
0

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.

Vaud answered 20/1, 2009 at 17:30 Comment(2)
and this is relevant to my question in what way?Hulburt
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.Savoirvivre
V
0

it's an important language feature if you wrap your program around the evented paradigm of javascript.

// a key exists as a placeholder for something
if(obj[name] === null) 
// no key exists int eh hashtable that is in this object
if(obj[name] === undefined)

this is very useful if you are dealing with a set of data that needs a value to represent 'nothing' to indicate some action different from using 'nothing' to indicate the default action.

filter_func_pt = {
  date:function(d){ return Math.round(d.getTime()/1000);},
  user: null,
}

function transform(obj){
    var ret = {};
    for( var prop in obj){
       var f = filter_func_pt[prop];
       if(f)
          ret[prop] = f(obj);
       else if(filter_func_pt[prop] === null)
         continue;
       else
         ret[prop] == obj;
    }
  return ret;
}

var a = {
   date: new Date(),
   user: 'sam'
   votes: [23, 41, 55] 
};

var b = transform(a);

/* b = {
 *    date: 1298582417
 *    votes: [23, 41, 55]
 * }
 */

in the above code the null keyword and the undefined server very clear and different purposes. the lookup that is not found in the filter_func_pt object which returns undefined means to add the property to the return object as is, whereas a null value indicates that the value should be withheld, and not added, and the presence of any true value in this case represents a function used to transform the value before adding it to the ret object.

Virgy answered 24/2, 2011 at 21:25 Comment(1)
This 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.Raposa
R
0

null is beautiful

as are all other Types of Live Script.

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

Why would you want to say incorrect things?!

"null" is "empty Object" just like "0" is an "empty Number". 0, is nothing -yet it exists as a Type of a Number thing. null is of course also empty but "it is" and it's a well defined thing of an Object Type.

It common to speak of these thing as of "types", when they are not. In fact they are "categories". But that's over now.

So will stick to it to say that "null" is a Type of Object without a Kind. And "null" says "I very much exist[!], but I don't have content of my kind".

Whereas undefined lacks both the Type and the Kind where undefined happens to also be its Type definition. An undefined type of a type becomes its distinctive typology. A sort of a [does "nothing" exist and how do you define "nothing"?] question.

cite: undefined nor null can be returned from a constructor function, as both will be converter to an empty object

You've managed to once again say an incorrect thing. Of course not, the "undefined" is not an Object, its a plain Token which we humans understand; but contrary to that null is - and it's telling you that: its Type is correct, but the Kind you are looking for is not contained within it, or at least -not at this time. Come visit us later when we put\assign some object in\to it.

cite: The only real difference I can think of is that one evaluates to NaN, the other to 0 in numeric contexts.

That makes the whole point of their core distinction, as mentioned: undefined is a plain token and since it is made up of the same 'genetic' material as its distant relatives: strings, the [ +undefined ] operation will duck-convert it to NaN, similarly null will of course morph itself into a correct kind 0 \Number instead, and as opposed to undefined that will morph into a string (!which is not empty!) and that's exactly why it yields NaN instead. Where: +undefined >> +"undefined" >> NaN. Since numeric context expects explicit value.

While the Boolean context expects reference - finds nothing to convert and yields 'false'.

Let's cut through now...

cite: So once again: what's the practical use for seperate values for undefined and null?

I will try to give you only two empirical examples and hope to suffice

oElement.onclick >> null

//means -the property exists; its expected value is of Type: Object, and that oElement supports the "onclick" event!

oElement.innerText >> ""

//means - the property exists; its expected value is of Type: String, which means that oElement supports the "innerText" property.

on both cases -if you receive "undefined" it means that the property doesn't exist; is not supported or has a wrong (ua vendor) implementation.

Stay frost and have fun.

Raised answered 9/2, 2012 at 1:16 Comment(2)
Don't vandalize your posts, aeneas. Delete them (using the Delete button just above this comment) if you want to remove your contribution.Janiecejanifer
there is no delete button - but in case you see it -please click it!Raised
C
0

after reading amazing discussion regarding undefined vs null, little search on google took me to Mozilla Documentations https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null it is mentioned - null is often retrieved in a place where an object can be expected but no object is relevant.

Isn't is similar to Null object pattern https://en.wikipedia.org/wiki/Null_object_pattern

So i guess this make sense to have Null data type.

Documentation also mentioned as typeof null // "object" (not "null" for legacy reasons)

Not sure what legacy reasons are

Cestoid answered 17/3, 2018 at 10:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.