Ari
Ari

Reputation: 3669

Short Circuit Evaluation to undefined?

I am using short circuit evaluation to set a key in an object. For example:

var obj = {foo : 'bar'}
var obj2 = {}

obj2.somekey = obj.baz || obj.foo //will assign 'bar' to obj2.somekey

The only difference with my code from that above, is that instead of assigning obj.foo if obj.baz doesn't exist, I would like obj.somekey to stay undefined. I tried obj2.somekey = obj.baz ||, but it threw me a syntax error.

Note that null and undefined, as this question suggests, are not actually undefined either.

So is there any way I can do this with short circuit syntax?

Upvotes: 2

Views: 3204

Answers (2)

Felix Kling
Felix Kling

Reputation: 816610

I would like obj.somekey to stay undefined.

Just to be clear: There is a difference between a property being undefined (with which I mean "it doesn't exist") and a property having the value undefined. No matter what you do, if you write

obj.somekey = ...;

the property will be created and will turn up in for...in loops for example.

If you really want to create the property only when the other property exists, you have to use an if statement:

if (obj.baz) {
   obj.somekey = obj.baz;
}

or the slightly less readable form***:

obj.baz && (obj.somekey = obj.baz)

Because of short circuiting, the right hand operand will only be evaluated if the left hand operand evaluates to true.


* Personally I advocate against this style, because it uses the AND operator for side effects, and doesn't do anything with the return value. The situations where you have to use this style, because you are forced to use an expression, are probably pretty rare.

Upvotes: 2

p.s.w.g
p.s.w.g

Reputation: 149020

It seems like the simplest solution would be:

obj2.somekey = obj.baz;

But if you really want the semantics of the logical operator (i.e. empty string, null, 0, NaN, and false, all evaluate to false and so || returns whatever is on the right), use void:

obj2.somekey = obj.baz || void(0);

Note that in this case the property .somekey will be assigned, but the value assigned to it may be undefined. See Felix Kling's excellent answer for a full explanation. To leave the property .somekey itself undefined simply use:

if ('baz' in obj) obj2.somekey = obj.baz;

Or to leave .somekey undefined even if .baz is falsey, use:

if (obj.baz) obj2.somekey = obj.baz;

Upvotes: 2

Related Questions