Reputation: 939
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
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
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
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 justprop && ...
?
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