Reputation: 23
Having the code:
foo = {};
foo.bar = 78;
foo.bar.baz = null;
testing foo.bar.baz
against null
:
if( foo.bar.baz === null )
console.log("foo.bar.baz is null");
else
console.log("foo.bar.baz is NOT null");
results in "foo.bar.baz is NOT null". Why isn't it null
since i set it up explicitly?
Upvotes: 2
Views: 70
Reputation: 19382
Working with numeric value as object in strict mode will run into exception.
By default foo.bar.baz = null
will be undefined because foo.bar
is not object and .baz
will not be set.
This is Your code in strict mode:
'use strict';
var foo = {};
foo.bar = 78;
foo.bar.baz = null;
if(foo.bar.baz === null )
alert("foo.bar.baz is null");
else
alert("foo.bar.baz is NOT null");
here is solution:
'use strict';
var foo = {};
foo.bar = {};
foo.bar.num = 78; // your number here
foo.bar.baz = null;
if( foo.bar.baz === null )
alert("foo.bar.baz is null");
else
alert("foo.bar.baz is NOT null");
p.s. always put 'use strict'
inside Your JS files to be able to make JS less versatile.
Upvotes: 1
Reputation: 1075925
Because primitives don't have properties, and the value in foo.bar
is a primitive.
When you access (get or set) a property on a primitive, the JavaScript engine creates an object for that primitive, sets or retrieves the property value (if any), and then throws away the object. (That's why (42).toString()
works; the primitive is promoted to an object backed by Number.prototype
, toString
is retrieved from that object and called with this
referring to the object, and then the object is thrown away.)
So although an object was created in your foo.bar.baz = null
statement, and its baz
property was set to null
, that object was never stored anywhere (certainly not in foo.bar
), and so it got thrown away. Later when you do if (foo.bar.baz === null)
, a new object, which doesn't have the property, is created and you get undefined
for its baz
property (because it doesn't have one). (Naturally, JavaScript engines can optimize this process to avoid unnecessary object creation.)
We could create a function on Number.prototype
that returned the object that gets created, to demonstrate that the object creation really does happen each time you access a property on a primitive:
// Add a `nifty` method to numbers
Object.defineProperty(
Number.prototype,
"nifty",
{
value: function() {
console.log("Number#nifty called");
return this;
}
}
);
var n = 42; // A primitive number
console.log(typeof n); // "number"
var obj1 = n.nifty(); // Creates an object, which we keep
console.log(typeof obj1); // "object"
var obj2 = n.nifty(); // Do it again, and a new object is created
console.log(obj1 === obj2); // false, they're not the same object
If you want to set properties on a number and keep them, you can do that by explicitly creating a Number
object:
var n = new Number(42);
n.baz = null;
console.log(n.baz === null); // true
It's rare to want to do that, but it's possible. Just beware that as we showed earlier, two Number
objects with the same raw value are not ==
to each other:
var n1 = new Number(42);
var n2 = new Number(42);
console.log(n1 == n2); // false
console.log(n1 === n2); // false
>
, <
, >=
, and <=
will coerce the number back to a primitive and use the raw value, but ==
and ===
will not.
Upvotes: 4
Reputation: 459
foo.bar
is a number primitive, not an object. You can't set properties on a number primitive, but you can set properties on a number object.
foo = {};
foo.bar = new Number(78);
foo.bar.baz = null;
Now foo.bar.baz == null
.
Upvotes: 0
Reputation: 9804
This is because
foo = {};
foo.bar = 78;
foo.bar.baz = null;
console.log(foo.bar.baz); // undefined
since you are trying to set a property of a number.
Upvotes: 0