When you assign a property like this:
var obj = {
a : undefined // or any other value
};
this happens according to the ECMAScript spec:
11.1.5 Object Initialiser
[...]
The production PropertyNameAndValueList : PropertyAssignment is evaluated as follows:
- Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
- Let propId be the result of evaluating PropertyAssignment.
- Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
- Return obj.
When you assign a property like this:
obj.a = undefined;
this happens according to the ECMAScript spec:
8.12.5 [[Put]] ( P, V, Throw )
[...]
- Else, create a named data property named P on object O as follows
a. Let newDesc be the Property Descriptor
{[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.
b. Call the [[DefineOwnProperty]] internal method of O passing P, newDesc, and Throw as arguments.
In either case, since undefined
and null
are legimite values, this will just define the property with this value.
Finally, hasOwnProperty()
will only check if a property descriptor was created, the value does not matter:
15.2.4.5 Object.prototype.hasOwnProperty (V)
[...]
- Let desc be the result of calling the [[GetOwnProperty]] internal method of O passing P as the argument.
- If desc is undefined, return false.
- Return true.
But, according to the ECMAScript spec, both a property set to undefined
and a not set property, will return undefined
if you access them:
8.12.3 [[Get]] (P)
[...]
- If desc is undefined, return undefined.
- If IsDataDescriptor(desc) is true, return desc.[[Value]].
- Otherwise, IsAccessorDescriptor(desc) must be true so, let getter be desc.[[Get]].
- If getter is undefined, return undefined.
- Return the result calling the [[Call]] internal method of getter providing O as the this value and providing no arguments.
Proof:
var obj = {
a : undefined
}
console.log(typeof obj.a); // undefined
console.log(typeof obj.b); // undefined
obj.hasOwnProperty('a') // true
obj.hasOwnProperty('b') // false
Only delete
will remove the property.
var obj = {
a : null,
b : undefined
}
obj.hasOwnProperty('a') // true
obj.hasOwnProperty('b') // true
delete obj.a;
delete obj.b;
obj.hasOwnProperty('a') // false
obj.hasOwnProperty('b') // false
Reading the ECMAScript spec on delete
is left to the reader.