开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜