Javascript Style Tip: Use "in" and "delete" #
Javascript provides two very handy operators, in and delete.
Consider this code fragment:
var obj = {
foo : 'quux',
bar : 'baz',
doSomething : function () {
// do something...
}
};
So, weâve created an object, and then some other things happen. Later in the code, we want to remove the âfooâ property, so we do this:
obj.foo = undefined;
Still later, we only want to do something if the foo property has not been unset, so we check it:
if ( obj.foo !== undefined ) {
// do something
}
That works, and itâs fairly common, but itâs klunky, and not as readable as this:
delete obj.foo;
if ( 'foo' in obj ) {
// do something
}
The first one says, Delete âfooâ from the object.
The second asks, Is âfooâ in the object?
The difference between the first and second approaches is that the second uses intuitive wording in the code.
Note: You must use delete
if you want to use in
. Setting something to undefined
manually will not cause it to return false when testing whether the property is in
the object.
As an added bonus, using the delete
operator also removes the property from the for/in iteration loop, since it actually removes it from the objectâs key list rather than simply setting itâs value to undefined
.
var obj = {asdf:'foo',bar:'baz'};
obj.asdf = undefined;
for ( var i in obj ) {
console.log(i,obj[i]);
}
// outputs:
// asdf undefined
// bar baz
var obj = {asdf:'foo',bar:'baz'};
delete obj.asdf;
for ( var i in obj ) {
console.log(i,obj[i]);
}
// outputs:
// bar baz
Note: youâll need to wrap the âinâ statement in parentheses if you want to negate it. For example, this is a bug:
var obj = { asdf:'foo',bar:'baz' };
var f = 'quux';
if ( !f in obj ) {
alert( 'not there!' );
}
The alert will never fire. Can you figure out whatâs happening? Hereâs a clue:
var obj = { 'false':1, asdf:'foo', bar:'baz' };
var f = 'quux';
if ( !f in obj ) {
alert( 'not there!' );
}
Now the alert will fire. Whatâs up?
The order of operations is this:
- Process the !f, which converts âquuxâ to a boolean (true), and then gets the opposite (false).
- The âinâ operator converts the value back to a string, and false.toString() is the string 'falseâ.
- Since 'falseâ is not a key in the object, the âinâ operator returns false, and the conditional fails.
In the second case, since the string 'falseâ is a key in the object, the âinâ operator returns true, and the conditional fires. Of course, using âfalseâ as a key in an object is a really stupid thing to do, but if some bunk data comes into your program somehow, it can happen. Always wrap your âinâ clauses in parentheses, and youâll never have a problem. In this case, it works as expected:
var obj = { asdf:'foo', bar:'baz' };
var f = 'quux';
if ( !(f in obj) ) {
alert( 'not there!' );
}
Update
Iâm finding that a lot of people are hitting this page with search queries that seem to indicate theyâre looking to remove a style property from a Dom node. delete
wonât help you much there, since the style
property is a get-and-set-only property. (IE, you can read from and write to it, but you canât delete from it.)
Most of the time, you shouldnât be messing with the style
property directly in Javascript, anyhow. Instead, add and remove semantically meaningful class names, and put the style information related to those states in the CSS. Of course thatâs not always an option, I know. So, you can remove the inline setting by simply setting it to an empty string, like this:
document.body.style.background="red"; // turns the page red.
document.body.style.background=""; // turns the page back to whatever it was.
Cheers!