Why is null
considered an object
in JavaScript?
Is checking
if ( object == null )
Do something
the
One way to make sense of null and undefined is to understand where each occurs.
Expect a null return value in the following situations:
Methods that query the DOM
console.log(window.document.getElementById("nonExistentElement"));
//Prints: null
JSON responses received from an Ajax request
{
name: "Bob",
address: null
}
RegEx.exec.
New functionality that is in a state of flux. The following returns null:
var proto = Object.getPrototypeOf(Object.getPrototypeOf({}));
// But this returns undefined:
Object.getOwnPropertyDescriptor({}, "a");
All other cases of non-existence are denoted by undefined (as noted by @Axel). Each of the following prints "undefined":
var uninitalised;
console.log(uninitalised);
var obj = {};
console.log(obj.nonExistent);
function missingParam(missing){
console.log(missing);
}
missingParam();
var arr = [];
console.log(arr.pop());
Of course if you decide to write var unitialised = null; or return null from a method yourself then you have null occurring in other situations. But that should be pretty obvious.
A third case is when you want to access a variable but you don't even know if it has been declared. For that case use typeof to avoid a reference error:
if(typeof unknown !== "undefined"){
//use unknown
}
In summary check for null when you are manipulating the DOM, dealing with Ajax, or using certain ECMAScript 5 features. For all other cases it is safe to check for undefined with strict equality:
if(value === undefined){
// stuff
}
From "The Principles of Object-Oriented Javascript" by Nicholas C. Zakas
But why an object when the type is null? (In fact, this has been acknowledged as an error by TC39, the committee that designs and maintains JavaScript. You could reason that null is an empty object pointer, making "object" a logical return value, but that’s still confusing.)
Zakas, Nicholas C. (2014-02-07). The Principles of Object-Oriented JavaScript (Kindle Locations 226-227). No Starch Press. Kindle Edition.
That said:
var game = null; //typeof(game) is "object"
game.score = 100;//null is not an object, what the heck!?
game instanceof Object; //false, so it's not an instance but it's type is object
//let's make this primitive variable an object;
game = {};
typeof(game);//it is an object
game instanceof Object; //true, yay!!!
game.score = 100;
Undefined case:
var score; //at this point 'score' is undefined
typeof(score); //'undefined'
var score.player = "felix"; //'undefined' is not an object
score instanceof Object; //false, oh I already knew that.
TLDR
undefined
is a primitive value in JavaScript that indicates the implicit absence of a value. Uninitialized variables automatically have this value, and functions without an explicit return
statement, return undefined
.
null
is also a primitive value in JavaScript. It indicates the intentional absence of an object value. null
in JavaScript was designed to enable interoperability with Java.
typeof null
returns "object"
because of a peculiarity in the design of the language, stemming from the demand that JavaScript be interoperable with Java. It does not mean null
is an instance of an object. It means: given the tree of primitive types in JavaScript, null
is part of the "object-type primitive" subtree. This is explained more fully below.
Details
undefined
is a primitive value that represents the implicit absence of a value. Note that undefined
was not directly accessible until JavaScript 1.3 in 1998. This tells us that null
was intended to be the value used by programmers when explicitly indicating the absence of a value. Uninitialized variables automatically have the value undefined
. undefined
is a one-of-a-kind type in the ECMAScript specification.
null
is a primitive value that represents the intentional absence of an object value. null
is also a one-of-a-kind type in the ECMAScript specification.
null
in JavaScript was designed with a view to enable interoperability with Java, both from a "look" perspective, and from a programatic perspective (eg the LiveConnect Java/JS bridge planned for 1996). Both Brendan Eich and others have since expressed distaste at the inclusion of two "absence of value" values, but in 1995 Eich was under orders to "make [JavaScript] look like Java".
Brendan Eich:
If I didn't have "Make it look like Java" as an order from management, and I had more time (hard to unconfound these two causal factors), then I would have preferred a Self-like "everything's an object" approach: no Boolean, Number, String wrappers. No undefined and null. Sigh.
In order to accommodate Java's concept of null
which, due to the strongly-typed nature of Java, can only be assigned to variables typed to a reference type (rather primitives), Eich chose to position the special null
value at the top of the object prototype chain (ie. the top of the reference types), and to include the null
type as part of the set of "object-type primitives".
The typeof
operator was added shortly thereafter in JavaScript 1.1, released on 19th August 1996.
From the V8 blog:
typeof null
returnsobject
, and notnull
, despitenull
being a type of its own. To understand why, consider that the set of all JavaScript types is divided into two groups:
- objects (i.e. the Object type)
- primitives (i.e. any non-object value)
As such,
null
means “no object value”, whereasundefined
means “no value”.
Following this line of thought, Brendan Eich designed JavaScript to make
typeof
return 'object' for all values on the right-hand side, i.e. all objects and null values, in the spirit of Java. That’s whytypeof null === 'object'
despite the spec having a separatenull
type.
So Eich designed the heirarchy of primitive types to enable interoperability with Java. This led to him positioning null
along with the "object-type primitives" on the heirarchy. To refelct this, when typeof
was added to the language shortly thereafter, he chose typeof null
to return "object"
.
The surprise expressed by JavaScript developers at typeof null === "object"
is the result of an impedance mismatch (or abstraction leak) between a weakly-typed language (JavaScript) that has both null
and undefined
, and another, strongly-typed language (Java) that only has null
, and in which null
is strictly defined to refer to a reference type (not a primitive type).
Note that this is all logical, reasonable and defensible. typeof null === "object"
is not a bug, but a second-order effect of having to accommodate Java interoperability.
A number of imperfect backwards rationalisations and/or conventions have emerged, including that undefined
indicates implicit absence of a value, and that null
indicates intentional absence of a value; or that undefined
is the absence of a value, and null
is specifically the absence of an object value.
A relevant conversation with Brendan Eich, screenshotted for posterity:
typeof null; // object
typeof undefined; // undefined
The value null represents the intentional absence of any object value. It is one of JavaScript's primitive values and is treated as falsy for boolean operations.
var x = null;
var y;
x is declared & defined as null
y is declared but not defined. It is declared with no value so it is undefined.
z is not declared so would also be undefined if you attempted to use z.
2.Undefined is a type itself while Null is an object.
3.Javascript can itself initialize any unassigned variable to undefined but it can never set value of a variable to null. This has to be done programatically.
null
is not an object, it is a primitive value. For example, you cannot add properties to it. Sometimes people wrongly assume that it is an object, because typeof null
returns "object"
. But that is actually a bug (that might even be fixed in ECMAScript 6).
The difference between null
and undefined
is as follows:
undefined
: used by JavaScript and means “no value”. Uninitialized variables, missing parameters and unknown variables have that value.
> var noValueYet;
> console.log(noValueYet);
undefined
> function foo(x) { console.log(x) }
> foo()
undefined
> var obj = {};
> console.log(obj.unknownProperty)
undefined
Accessing unknown variables, however, produces an exception:
> unknownVariable
ReferenceError: unknownVariable is not defined
null
: used by programmers to indicate “no value”, e.g. as a parameter to a function.
Examining a variable:
console.log(typeof unknownVariable === "undefined"); // true
var foo;
console.log(typeof foo === "undefined"); // true
console.log(foo === undefined); // true
var bar = null;
console.log(bar === null); // true
As a general rule, you should always use === and never == in JavaScript (== performs all kinds of conversions that can produce unexpected results). The check x == null
is an edge case, because it works for both null
and undefined
:
> null == null
true
> undefined == null
true
A common way of checking whether a variable has a value is to convert it to boolean and see whether it is true
. That conversion is performed by the if
statement and the boolean operator ! (“not”).
function foo(param) {
if (param) {
// ...
}
}
function foo(param) {
if (! param) param = "abc";
}
function foo(param) {
// || returns first operand that can't be converted to false
param = param || "abc";
}
Drawback of this approach: All of the following values evaluate to false
, so you have to be careful (e.g., the above checks can’t distinguish between undefined
and 0
).
undefined
, null
false
+0
, -0
, NaN
""
You can test the conversion to boolean by using Boolean
as a function (normally it is a constructor, to be used with new
):
> Boolean(null)
false
> Boolean("")
false
> Boolean(3-3)
false
> Boolean({})
true
> Boolean([])
true