JavaScript idiom: !something && function()
I have been looking at the source code of raphael.js and I see a lot of stuff like !variable && function()
(e.g.: !svg.bottom && (svg.bottom =开发者_StackOverflow中文版 this);
)
What does that exactly do? Does it check first and execute only if not true?
Correct. This is (ab)using short-circuit evaluation. A boolean expression is only executed as far as is needed to determine the result. In your example, if svg.bottom
is non-null, then !svg.bottom
is false
, and the result of the &&
is false
, so execution of the right hand side does not happen. It's basically equivalent to if(!svg.bottom)svg.bottom = this;
When you have boolean operations, the compiler start check one by one each condition, and stops when its sure for the results - for example if you ask
if(a && b && c)
{
}
if a is false, then the full boolean question is false, and compiler did not need to check b and c. This compiler feature is used to short the writing code for some cases.
This is (for me) a bad practice that writing code like.
!variable && function()
instead of
if(!variable) function();
try to minimize the size of the javascript ?
Difficult to debug, and difficult to find what actually dose in many cases.
See this similar code.
unsigned uCycleCheckBox(unisgned uCur)
{
return ((uCur <= 1) ? (uCur?0:1) : (uCur==4)?2:(uCur+1));
}
is the same think... hard to understand, hard to debug, hard to change and fix in case of problems.
For the comments on that, I suggest to read the books, Writing Solid Code, and Debugging the development process.
Writing solid code is more important than everything else.
It uses short-circuiting rules to perform the second part of the expression (which actually includes assignment) only if the first part (!svg.bottom
) is not false. That is if svg.bottom is null
- set it to this
.
There are two handy ways of using logical operators in JS, because they are not merely boolean operators.
With &&
, you can say "if this expression is true, it's safe to evaluate the next expression". The most common usage is to check if a property is non-null before digging further inside it:
var result = myObj.person && myObj.person.firstName;
If myObj.person
is undefined, the value of result
will be undefined also.
With ||
, you can say "take the value of this expression if it's truthy (not null or undefined in this context), otherwise use a default":
var result = person.firstName || "Sid";
Combining the two:
var result = (myObj.person && myObj.person.firstName) || "Sid";
A quick way to say "get the firstName
from the person
property of myObj
, or use "Sid" if the person
has no firstName
or myObj
has no person
".
The example you refer to is a bit strange though. Doing a side-effecting operation inside an expression is a bit ugly. It's usually easier to keep track of what you're program is doing if you clearly separate "read-only" expressions from variable-mutating statements.
UPDATE:
Two more recent features improve on this. First, ?.
var result = (myObj.person?.firstName) || "Sid";
And second, ??
, which may be closer to the desired behaviour:
var result = (myObj.person?.firstName) ?? "Sid";
This means that "Sid"
will only be the result
if the right-side expression is null
or undefined
, where as ||
is much looser: "Sid"
will be the result
if the value is falsy, which includes null
, undefined
, false
, 0
, NaN
and (importantly here) the empty string.
Javascript has many strange casting conventions. The !
operator will cast to a boolean. If the test fails, the part after &&
will not be run.
Some examples:
!undefined
is true
!false
is true
!0
is true
!1
is false
!"hello"
is false
精彩评论