tags:

views:

96

answers:

5

Hi Stackoverflow,

I have been looking at the source code of raphael (http://raphaeljs.com/index.html) and I see a lot of stuff like !variable && function() (e.g.: !svg.bottom && (svg.bottom = this); )

What does that exactly do? Does it check first and execute only if not true?

Thanks.

+6  A: 

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.

EFraim
`!svg.bottom ` is quite weird though... It would be simpler to just do `svg.bottom = svg.bottom || this`.
J-P
@EFraim, not only if `svg.bottom` is `null`, also if it's `undefined`, `0`, `NaN` an empty string, and of course `false`.
CMS
Yeah, its like abbreviated 'if' statement, although it would be clearer to use if (!svg.bottom) { svg.bottom = this;}
Pablo Cabrera
@Vivin put the second expression between parenthesis, it should do the trick
Pablo Cabrera
+1  A: 

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;

Yuliy
A: 

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

z5h
!"hello" is false...
Pablo Cabrera
Though I believe `!""` is `true`.
Daniel Earwicker
That's correct. Check the spec: =]http://bclary.com/2004/11/07/#a-9.2
Pablo Cabrera
whoops! thank you Pablo.
z5h
A: 

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.

Daniel Earwicker
+2  A: 

When you have boolean operations, the compiler start check the one by the other, and stop when its sure for the results - for example if you ask

if(a && b && c)
{    
}

if a is false, then the boolean is false, and compiler did not need to check b and c. This compiler future is used to short the writing code for some cases.

This is (for me) a bad practice that writing code.

!variable && function() 

instide of

if(!variable) function();

try to minimize the size of the javascript ?

Dificult to debug, and dificult 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 Debbuging the deveopment process.

Writing solid code is more important than enything else.

Aristos
Maybe they're code-golfing ;)
KennyTM
What is hard to understand?! ;)
EFraim
And only the existing of the question, must make you think again, yes is hard to fast understand what the code dose, its also dificult to debug, and imaging that the code is not only for the one that write it.
Aristos