Search code examples
javascripthtmleventsboolean-expression

Can a conditional-And operator(&&) contain more than 2 operands?


I asked a question in regards to this code earlier and it works to a degree after I changed it to reflect the answer but there is a bug that only really you to match red with red or blue with blue or green with green. I know that the problem lies within the checkColors function. Basically I want to know if it would be possible to change

if (squares1[0].style.backgroundColor=='rgb(255, 0, 0)' &&      squares2[0].style.backgroundColor=='rgb(255, 0, 0)'){
    squares3[0].style.backgroundColor='rgb(255, 0, 0)';
    gotIt;

to

if (squares1[0].style.backgroundColor=='rgb(255, 0, 0)' && squares2[0].style.backgroundColor=='rgb(255, 0, 0)') &&
    squares3[0].style.backgroundColor='rgb(255, 0, 0){
    gotIt;}

or something of the sort. This function pretty much destroys the whole thing and I was wondering if the above or something similar is possible because the checkColor function seems to change the colors of the third square every time.

I updated my fiddle and it shows the purpose of the gotIt function. http://jsfiddle.net/j6xrxbeb/

The original purpose was for the color of the two left divs to make up the color of the div of the right.


Solution

  • Basically I want to know if it would be possible to change...to...or something of the sort.

    Yes, and the way you did it is how you would do it, other than typos. E.g.:

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

    is equivalent to

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

    I found this page. msdn.microsoft.com/en-us/library/2a723cdk.aspx that only shows them as x&&y so I thought I could only use 2

    Which is correct as far as it goes: The && operator, like most operators in the JavaScript language, is a binary operator: It accepts two operands. (JavaScript also has several unary operators [operators accepting one operand], like negation and such, and one ternary operator [an operator accepting three operands]). The addition (+) and subtraction (-) operators are also binary operators: They work with two operands.

    However: Just like addition and subtraction, with && you can use the result of one expression to feed into another. So just like we can write:

    a + b - c
    

    ...and the engine evaluates a + b, getting the value r, and then evaluates r - c, we can do:

    if (a && b && c)
    

    and it's evaluated like this:

    1. a && b is evaluated, and we get a result r

    2. r && c is evaluated

    It happens that way because && is evaluated left-to-right. You can combine as many expressions together this way as you like:

    if (a && b && c && d && e && f && g)
    

    Just for completeness: Not all expressions are evaluated left-to-right, and some operators get to jump the queue and go first. This is called "operator precedence." For example, * has higher precedence than the binary +, so if we write

    1 + 2 * 3
    

    the result is 7, not 9 — the * got to go first, giving us 2 * 3 = 6 and then 1 + 6 = 7.


    The problem with your checkColors function is that it relies on the value coming back being in rgb(r, g, b) form, but many browsers use a different form (regardless of the form you used when specifying the color). It could be rgba(r,g,b,a) or rgb(r,g,b) or #rrggbb or blue...you get the idea.

    Instead, keep track of the color you've assigned (in the form you're using) in another location, perhaps a data-* attribute. Then you know that later, when you compare something with that color, it will be in the form you expect. Or you can track it as a state variable in your code. There are several ways to track this information.

    Here's a much simpler example:

    Array.prototype.forEach.call(
      document.querySelectorAll(".toggle"),
      function(div) {
        div.addEventListener("click", colorClick, false);
      }
    );
    function colorClick() {
      var color = this.getAttribute("data-color");
      if (!color || color === "blue") {
        color = "green";
      } else {
        color = "blue";
      }
      this.style.backgroundColor = color;
      this.setAttribute("data-color", color);
    }
    div {
      color: white;
      border: 1px solid black;
      display: inline-block;
      width: 100px;
      height: 50px;
    }
    <div class="toggle" style="background-color: blue">Click me</div>
    <div class="toggle" style="background-color: blue">Click me</div>
    <div class="toggle" style="background-color: blue">Click me</div>
    <div class="toggle" style="background-color: blue">Click me</div>