0

edit : Quote removed. is not related to the question.

Question

How come does it always (when all are truthy) takes the last value ?

Examples :

f= 1 && 2 && 3 //3

f= 'k' && 'd' && 's' //'s'

p.s. : I've noticed that when investigating the pub/sub using $.callbacks

enter image description here

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • 5
    The `&&` operator is supposed to be used with boolean operands. But since javascript allows for writing such weakly typed pornography, the result is, well, surprising :-) – Darin Dimitrov Oct 07 '13 at 08:04
  • This is for the performance of execution as the **AND** is to return true when all the conditions are correct. It will stop checking when the first one fails because the condition will return false when anyone of it is false. So there is no need of checking the next. – Marikkani Chelladurai Oct 07 '13 at 08:07

7 Answers7

6

Operator && acts as an if-statement. The short-circuit occurs only if a value is false. Otherwise, it keeps evaluating statements.

When you write a && b it means: a ? b : a. Similarly, a || b means: a ? a : b.

Guillaume Poussel
  • 9,572
  • 2
  • 33
  • 42
  • looking at your answer more deeply - it actually answer my question. since this acts like a chain. if `A` then `B` and (same round) if `B` then C - which means im left with `C`. – Royi Namir Oct 07 '13 at 08:13
  • The `||` is deeply used to assign default value to a variable, like this: `setting = setting || false` will assign false if no value are provided by the user (i.e. `undefined`) – Guillaume Poussel Oct 07 '13 at 08:16
4

Edit: author has clarified the question significantly.

JavaScript logical AND operator return the left operand if it is falsy or else it returns the right operand. Let us take a look at the table of logical truth:

A     B     A && B
true  true  true
true  false false
false true  false
false false false

As you can see, if A is false, we can return it:

A     A && B
false false
false false

If A is not false, we can return B:

B     A && B
true  true
false false

This is a minor optimization, which leads to interesting sideeffects when used with weak typing, such as inline if:

var result = callback && callback()

// Generally equivalent to a simple if:
if (callback)
    result = callback();
else
    result = null;

Also using default options:

name = name || 'John';

// Generally equivalent to a simple if:
if (!name)
    name = 'John';

As to why it happens, well, because these operators are defined like that in ECMA-262.

Denis
  • 5,061
  • 1
  • 20
  • 22
3

So how come does it always (when all are truthy) takes the last value ?

Because it can't short-circuit if the leading values are truthy, because it's an "AND" operator, and all operands must be truthy to satisfy the condition.


Re your comment below:

yes but why does it returns the last value ?

Because it's useful. :-) In the very first version of JavaScript from Netscape, it just returned true if the overall expression was true and false if not, but almost immediately they realized that it's much more useful if it returns the final operand.

For instance, you can do this:

var value = obj && obj.value;

...which will set value to be either a falsey value (if obj is falsey) or obj.value (if obj is not falsey). Importantly, it won't throw an error if obj is falsey. Very handy for guarding if you don't know for sure that obj is set. You don't have to stop at one level, either:

var value = obj && obj.sub && obj.sub.value;

value will either be falsey, or the value of obj.sub.value if both obj and obj.sub are truthy (e.g., because we seem to be using them as objects, they're object instances rather than null or undefined).

|| does the same sort of thing: It returns its first truthy operand.

More: JavaScript's Curiously Powerful OR Operator (||)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

&& is a logical operator. This tests whether a value is truthy or falsy. This linked article explains that falsy values are equal to undefined, null, NaN, 0, "" and false.

Logical expressions are checked from left to right. If any part of the expression is evaluated t be falsy, the remainder of the expression will not be evaluated. In your examples, the value is always truthy. Here we can break down your first expression:

f = 1 && 2 && 3;
f = 1 /* Okay, 1 is a truthy value, lets continue... */
f = 2 /* Still truthy, let's continue... */
f = 3 /* Still truthy, we've reached the end of the expression, f = 3. */

If any of the values before 3 were falsy, the expression would have ended. To show this in action, simply redeclare your variable as:

f = 1 && 2 && 0 && 3;

Here 0 is a falsy value (as mentioned above). The execution of your expression here will end at 0:

f = 1 /* Okay, 1 is a truthy value, lets continue... */
f = 2 /* Still truthy, let's continue... */
f = 0 /* Hey, this is falsy, lets stop here, f = 0. */
f = 3 /* We never get here as the expression has ended */

Here f ends up being 0.

In your jQuery.Topic() example, && is used to ensure that id actually exists:

topic = id && topics[id]

We can break this down in the same way:

/* Assume this is your topics array: */
topics = ["", "My First Topic", "My Second Topic"];

/* If we pass in the value 1 as "jQuery.Topic(1)": */
topic = id && topics[id]
topic = 1 /* This is truthy, let's continue... */
topic = topics[1] /* topics[1] === "My First Topic" */

/* Now lets assume we pass in nothing as "jQuery.Topic()": */
topic = id && topics[id]
topic = null /* This is falsy, let's stop here, topic = null. */

The following if statement will only work if topic is truthy. In the first example, this is the case as topic has a value which is set to a string which isn't empty. In the second example, topic is null which is falsy.

James Donnelly
  • 126,410
  • 34
  • 208
  • 218
  • It's an expression, not a statement. And it also does not take multiple operands, it's just multiple `&&` expressions: `1 && (2 && (0 && 3))`. – Denis Oct 07 '13 at 08:13
1

Because if first one is truthy, then it should go on and check second operand till the last one. If you would go with 1 || 2 || 3 instead it will return 1.

Alexander Taran
  • 6,655
  • 2
  • 39
  • 60
1

The ECMAScript Standard states 12.11.2 Runtime Semantics: Evaluation:

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression

1. Let lref be the result of evaluating LogicalANDExpression.
2. Let lval be GetValue(lref).
3. Let lbool be ToBoolean(lval).
4. ReturnIfAbrupt(lbool).
5. If lbool is false, return lval.
6. Let rref be the result of evaluating BitwiseORExpression.
7. Return GetValue(rref).

That is, first we check whether the first operand is evaluated to be a "falsy" value (null, false, 0). If it is, then the first operand is returned.

If, however, it's "thruthy", then the same process is repeated for the second operand and if it is evaluated as a truthy value, then the original value is returned (7. Return GetValue(rref)).

Saebekassebil
  • 714
  • 5
  • 10
0

Short-circuit evaluation and returning the second expression instead of a bool are quite useful features.

The && operator evaluates the left operand and if it's truthy evaluates the right operand. Similarly the || operator evaluates the left operand and if it's falsy evaluates the right operand.

This allows to write things like

draw_element(color || "#F00");

with the meaning of using color unless if it's not specified (e.g. color is null, undefined or "") and in that case the default value is used.

You can even use things like

draw_element(color || pick_new_color());

and the function pick_new_color() will be called only if a color is not specified.

A very common use of && instead is to avoid errors, e.g:

if (x && x.constructor == Array) {
    ...
}

because if x is null or undefined you cannot access attributes (an exception would be raised if you try). The fact that && returns the first result if it's falsy instead of just false is not so useful indeed. Your code example does it, but it's not something you will find often in Javascript programs.

To recap: && and || are short-circuiting (i.e. they don't even evaluate the second operand if the result is known after evaluating the first) and this is very useful. They also return the falsy/truthy value itself instead of a bool, and this is very useful for || (not so much useful for &&).

6502
  • 112,025
  • 15
  • 165
  • 265