06 - Testing and Deleting Properties
Deleting Properties
The delete
operator removes a specified property from an object. Its single operand should be a property access expression.
delete does not operate on the value of the property but on the property itself:
delete book.author;
// The book object now has no author property.
delete book["main title"];
// Now it doesn't have "main title", either.
delete day1.squirrel;
console.log(day1.squirrel); // undefined
The delete operator only deletes own properties, not inherited ones. To delete an inherited property, you must delete it from the prototype object in which it is defined. Doing this affects every object that inherits from that prototype.
Testing Properties
To test for membership in a set — to check whether an object has a property with a given name — you can use the in
operator, the hasOwnProperty()
method, the propertyIsEnumerable()
method, or simply query the property directly.
The ‘in’ Operator
The in
operator expects a property name on its left side and an object on its right. It returns true
if the object has an own property or an inherited property with that name:
let o = { x: 1 };
"x" in o
// => true: o has an own property "x"
"y" in o
// => false: o doesn't have a property "y"
"toString" in o
// => true: o inherits a toString property
Instead of using the in
operator, it is often sufficient to simply query the property and use !==
to make sure it is not undefined
:
let o = { x: 1 };
o.x !== undefined
// => true: o has a property "x"
o.y !== undefined
// => false: o doesn't have a property "y"
o.toString !== undefined
// => true: o inherits a toString property
The Difference Between ‘in’ and Direct Property Access
There is one thing the in
operator can do that the simple property access technique cannot: in
can distinguish between properties that do not exist and properties that exist but have been set to undefined
.
let o = { x: undefined };
o.x !== undefined // => false: property exists but is undefined
o.y !== undefined // => false: property doesn't exist
"x" in o // => true: the property exists, even though it's undefined
"y" in o // => false: the property doesn't exist
delete o.x;
"x" in o // => false: the property doesn't exist anymore
The ‘hasOwnProperty()’ Method
The hasOwnProperty()
method of an object tests whether that object has an own property with the given name. It returns false
for inherited properties:
let o = { x: 1 };
o.hasOwnProperty("x")
// => true: o has an own property "x"
o.hasOwnProperty("y")
// => false: o doesn't have a property "y"
o.hasOwnProperty("toString")
// => false: "toString" is an inherited property
The ‘propertyIsEnumerable()’ Method
The propertyIsEnumerable()
method refines the hasOwnProperty()
test. It returns true
only if the named property is an own property and its enumerable attribute is true
:
let o = { x: 1 };
o.propertyIsEnumerable("x")
// => true: o has an own enumerable property "x"
o.propertyIsEnumerable("toString")
// => false: "toString" is not an own property
Object.prototype.propertyIsEnumerable("toString")
// => false: "toString" is not enumerable