The value
null
represents the intentional absence of any object value.In APIs,
null
is often retrieved in place where an object can be expected but no object is relevant.— MDN (emphasis mine)
TL;DR: Why does null.content
throw an error but false.content
returns undefined
?
In my project’s API, I have methods allowing the user to set and get an icon of a Page.
Page.prototype.setIcon = function (key) {
this.icon = database.find(function (item) { return item.content === key })
}
Page.prototype.getIconContent = function () {
return this.icon.content
}
A string is given as the argument, and the program searches the database for an object whose content
property equals the given argument. If no such object is found, the find()
function will return undefined
. So this.icon
will be set to undefined
.
This is not good because when the user calls getIconContent()
, they will receive an error, because the program is trying to find the content
property of undefined
.
What I want to happen is that if no such object in the database is found, setIcon()
will set this.icon
to a falsy value that will not throw an error when attempting to get the content
property. So I tried using OR null
, as it is an object.
Page.prototype.setIcon = function (key) {
this.icon = database.find(function (item) { return item.content === key }) || null
}
But this didn’t work because trying to get null.content
will still throw an error. So then I tried OR false
and it works the way I want.
Page.prototype.setIcon = function (key) {
this.icon = database.find(function (item) { return item.content === key }) || false
}
So when a user calls setIcon()
with no argument, and then tries getIconContent()
, they will not receive an error, because false.content
doesn’t throw an error; it returns undefined
, which is the behavior I’m looking for.
My question is, why is false
the correct usage, when clearly the expected type of icon
should be an object? I would think null
would be more “semantically correct,” but it throws an error.
PS: In addition to false
, these are other falsy values that don’t throw errors:
var a = 0; a.content // returns `undefined`
var b = NaN; b.content // returns `undefined`
var c = ''; c.content // returns `undefined`
The empty object {}
, even though it is truthy
var d = {}; d.content // returns `undefined`
undefined
throws an error as expected
var e; e.content // throws an error "Uncaught ReferenceError: e is not defined"
false
is a boolean. Booleans are boxable (like numbers and strings) because there is a Boolean
constructor in the language. When you try to access false.content
, it becomes an object, nearly (but not quite, because it's still of type "boolean"
) what you'd get from new Boolean(false)
. Being an object, it can have properties. It's just that booleans have no useful properties (unlike strings which have length
etc) so you never see them used that way.
On the other hand, there is no Null
constructor that could box the value null
of type "null"
(or indeed type "object"
in older versions of ECMAScript). So there is no valid way to interpret null.content
.