webstackdev
webstackdev

Reputation: 939

Understanding conditional operator and assignment in condition in code snippet

I'm trying to understand how the third line in this code snippet (the assignment value = f in the condition of the conditional expression) is working:

someProp(propName, f) {
  let prop = this._props && this._props[propName], value
  if (prop != null && (value = f ? f(prop) : prop)) return value
  ...
}

In this example, value is undefined at the console.log(value) statement:

let f = 42;
value = f ? console.log('true') : console.log('false');
console.log(value);

It seems to me that the value variable returned on the third line of the first snippet would always be undefined. What am I missing? The snippet is from production code in an open source project I'm studying.

Also, this._props is an object. Why is the author using if (prop != null && ... to test if the props object exists, rather than just something like if (prop && ... ? And am I right in thinking that this is typical code of more experienced developers, or would others write it differently?

Upvotes: 0

Views: 56

Answers (3)

Ben West
Ben West

Reputation: 4596

Personally I think this is badly written; experience aside, it's too hard to read. Ternary inside an if condition which does an assignment which then may get returned - calm down.

Here it is longhand:

if ( prop != null ) {
    if ( f ) {
        value = f( prop );
    } else {
        value = prop;
    }
    if ( value ) return value;
}

An extra quirk is that value won't be returned if it's falsy, which (I guess) is why its assignment was part of the if condition. It is clever of the author to cram all this logic into one line but in my opinion it's better dumbed down.

Upvotes: 1

Luca Kiebel
Luca Kiebel

Reputation: 10096

Let's examine this line:

if (prop != null && (value = f ? f(prop) : prop)) return value

Especially this part:

(value = f ? f(prop) : prop) 

If f is truthy, set value to the return value of f(prop).

If f is not thruthy, set value to the value of prop.

Value is then checked for thruthyness and returned.


In your second example:

let f = 42;
value = f ? console.log('true') : console.log('false');
console.log(value);

What you are actually doing is setting value to the return value of console.log('true') which is always going to be undefined, since console.log() returns undefined.


And am I right in thinking that this is typical code of more experienced developers, or would others write it differently?

For easier understanding, and especially if the code is used in tutorials, I would personally expand the code for better readability among learners, but I also like my code compact, so if it was code for a library, I'd probably code along those lines too.

Upvotes: 1

Bergi
Bergi

Reputation: 665456

The conditional operator has a higher precedence than the assignment operator, so this is parsed

if (prop != null && (value = (f ? f(prop) : prop))) return value
//                           ^                  ^

not

if (prop != null && ((value = f) ? f(prop) : prop)) return value
//                   ^         ^

as you were expecting. So yes, in your demo example you always get undefined as that's the return value of the console.log calls. But here it is assigned either f(prop) or prop.

Also, why is the author using prop != null && ... rather than just prop && ...?

Because he likes being explicit.

And am I right in thinking that this is typical code of more experienced developers?

No. Possibly typical code of developers that were once bitten by falsy values.

Upvotes: 1

Related Questions