MulliGan81
MulliGan81

Reputation: 23

Setting a property to null

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

Answers (4)

num8er
num8er

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

T.J. Crowder
T.J. Crowder

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

hiy
hiy

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

Deep
Deep

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

Related Questions