user3389206
user3389206

Reputation: 495

meaning of the AND operator in this line

What is the meaning of && in this JavaScript code?

function doIt(a) {
    var b = a.parents(),
    c = 1;

    return b.each(function() {
        jQuery(this).hasClass("free-content") && (c = 0)
    }), c
}

normally I would think this would be a logical operator AND, but I can't figure out what it does in this line.

Upvotes: 3

Views: 104

Answers (2)

mekwall
mekwall

Reputation: 28974

The logical AND operator in this case is used in place of an IF-statement. It will set c to 0 if jQuery(this).hasClass("free-content") returns a truthy value.

It's equivalent to:

if (jQuery(this).hasClass("free-content")) {
    c = 0;
}

You wondering what it means is actually the reason I dislike this type of coding and consider it a bad practice. It's hard to read and can create confusion, which in turn can create bugs.


It's also worth noting what logical AND returns, if you want to use the returned value:

(Logical AND) Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.

Here's an example showing, in my opinion, bad code since it's hard to follow:

var foo = bar && baz || qux;

The above code is equivalent to:

var foo;
if (bar && baz) {
    foo = baz;
} else {
    foo = qux;
}

Summary: Do not use logical operators as a nifty way to replace IF-statements or to save keystrokes. It will most likely come back and bite you or someone else in the ass.

I know there will be people arguing against me on this (usually the same people who doesn't want to use semicolon because ASI), but it's just a really bad idea to write code that only an expert would understand. There's no argument against it.

Upvotes: 4

C3roe
C3roe

Reputation: 96306

return b.each(function () {

    jQuery(this).hasClass("free-content") && (c = 0)
}), c

b.each loops over all entries in b, and checks whether the current element has the class free-content set. Only if that yields true, the second part of the expression is evaluated – because they are concatenated via &&, and JavaScript stops evaluating such an expression when the first part is false, because then the whole expression can’t become true any more.

So if there is an element with that class, the second part is evaluated – and thereby c is set to the value 0 (because that’s the assignment operator = there, and not a comparison).

And after that each loop is finished, the value of c is returned to the outside – because each() and c are connected via the comma operator , here, which evaluates its operands from left to right and then “returns” the second one.


JavaScript allows a lot of “fancy” coding like this, but as Marcus already said in his answer, that is hard to read, and there is no actual advantage here over, say

b.each(function() {
    if(jQuery(this).hasClass("free-content")) {
      c = 0;
      return false;
    }
});
return c;

I added the return false here inside the each loop, because once we found an element with that class, we don’t need to search the rest of them any more – that’s something that the person who came up with the original code forgot to do in all their “fancy-ness” … their loop will continue to iterate over all of b’s elements, not matter if it finds the element it is looking for in the first round already.

Upvotes: 2

Related Questions