44

I saw somewhere else said,

x && foo();

 is equal to

if(x){
    foo();
}

I tested it and they really did the same thing.
But why? What exactly is x && foo()?

Community
  • 1
  • 1
Derek 朕會功夫
  • 84,678
  • 41
  • 166
  • 228
  • 29
    Even though this is a slick trick, I hope you don't use it. It works but it is considered bad form. – Charles Caldwell Aug 07 '11 at 02:37
  • 4
    Yeah, I agree with @PortableWorld. `if(x){foo();}` or even `if(x) foo();` on a single line would be just about as comprehensible, more general usage. – Kzqai Aug 07 '11 at 03:15
  • 4
    But be careful not to confuse this with `if( x && foo() ) { ... }` which is acceptable and has a different meaning. I, for one, don't mind `x && foo()`, especially if things like this creep up a lot... JS benefits from minimization. – vol7ron Aug 07 '11 at 03:32
  • 1
    @PortableWorld: it may be considered good form in other languages, however. I use it all the time in Bash (which lacks a one-line if statement), and I think it may be acceptable in Perl as well. – Ken Bloom Aug 07 '11 at 04:12
  • 11
    A good use of this idiom is `window.console && console.log('xyz');` to keep errant log commands from throwing errors in browsers that don't have the console enabled. – bbg Aug 07 '11 at 04:49
  • 10
    For the record I think this is beautiful. – NullUserException Aug 07 '11 at 07:24
  • 3
    `if(x) foo();` vs `x && foo();`. Ignoring whitespace, you are saving two characters. Who cares?! – Engineer Aug 07 '11 at 12:14
  • I'm with @PortableWorld. Seems like a cheap trick in most cases... – Matt Montag Aug 08 '11 at 09:06
  • 1
    @Nick_Wiggill It's more a matter of whether developers after you have to look it up to be certain about it's behavior, as Derek did. Readability issue over whitespace issue. – Kzqai Aug 09 '11 at 15:06
  • Duplicate http://stackoverflow.com/q/6829736/377133 – Sergey Metlov Aug 10 '11 at 07:54

5 Answers5

69

Both AND and OR operators can shortcut.

So && only tries the second expression if the first is true (truth-like, more specifically). The fact that the second operation does stuff (whatever the contents of foo() does) doesn't matter because it's not executed unless that first expression evaluates to something truthy. If it is truthy, it then will be executed in order to try the second test.

Conversely, if the first expression in an || statement is true, the second doesn't get touched. This is done because the whole statement can already be evaluated, the statement will result in true regardless of the outcome of the second expression, so it will be ignored and remain unexecuted.

The cases to watch out for when using shortcuts like this, of course, are the cases with operators where defined variables still evaluate to falsy values (e.g. 0), and truthy ones (e.g. 'zero').

Kzqai
  • 21,270
  • 21
  • 97
  • 131
  • 4
    Check your language's syntax specification to ensure that your language follows the same shortcut execution termination rule. Legacy languages do exist that violate it. – John Tobler Aug 07 '11 at 06:58
  • Actually, in Delphi you can switch it off for the whole project, a specific file, or even around a certain function.. Crazy stuff :) http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsbooleanshortcircuitevaluation_xml.html – Davy Landman Aug 07 '11 at 08:34
  • 5
    @John: The question specifies javascript… – Donal Fellows Aug 07 '11 at 15:05
24

This is known as short-circuit evaluation.

In this case, if x is False, then foo() doesn't need to be evaluated (the result of && will always be False); if x is True, it does need to be evaluated (even if the result is thrown away).

Johnsyweb
  • 121,480
  • 23
  • 172
  • 229
8

It's not exactly equivalent. The first one is an expression with a return value you can use; the second one is a statement.

If you are not interested in the return value (that is, the information whether both x and foo() evaluate to a truthy value), they are equivalent, but normally, you should use the boolean-logic version only if you want to use it as a boolean expression, e.g.:

if (x && foo()) {
    do_stuff();
}

If you are only interested in running foo() conditionally (when x is truthy), the second form is to be preferred, since it conveys the intention more clearly.

A reason people might prefer the boolean-logic version might be that javascript is subject to an unusual restriction: source code size (more verbose source code means more bandwidth used); since the boolean-logic version uses less characters, it is more bandwidth-efficient. I'd still prefer the more verbose version most of the time, unless the script in question is used a lot - for a library like jQuery, using optimizations like this is perfectly justifyable, but in most other cases it's not.

tdammers
  • 19,316
  • 1
  • 34
  • 53
3

In javascript, the && operator evaluates left to right and returns the value of the rightmost operation. If the first condition evaluates to false, it doesn't evaluate the second. So its a shorthand of saying "if something is not null or undefined, do something"

Mrchief
  • 70,643
  • 19
  • 134
  • 181
2

It is short circuiting.

The && operator works like this: It does the logical or of the two operands on both side. If the left hand side has a non zero value then the right hand side is evaluated to determine the truth value. If the left hand side is zero then whatever the right hand side be, the expression will evaluate to 0, therefore the right hand side is not evaluated. So in effect, if x is non-zero then only foo is called, and if x is 0 then foo is not called, and thus, it works like if - else in this case.

phoxis
  • 52,327
  • 12
  • 74
  • 110