And and Or in JS 13

The logical and (&&) and the logical or (||) are two really useful operators in JS. The following holds true:

  • a || b results in a if Boolean(a) == true, otherwise b
  • a && b results in b if Boolean(a) == true, otherwise a

Using this one can often simplify expression a lot. For example:

var el = e.target ? e.target : e.srcElement;

can be written as

var el = e.target || e.srcElement;

And using && we can make sure that an object exists before we access a field:

var el = document.getElementById && document.getElementById("my-el");
  • http://www.robertnyman.com Robert Nyman

    var el = e.target || e.srcElement;

    Hmm, that was interesting. Guess I never thought of it that way, I’ve always used the ternary expression you showcased.

    Would you say that the OR operator is good (better) practice in that case?

  • M. Schopman

    As always, it depends. I personally tend to use the ternary and the shorthand ternary as little as possible since it makes code harder to understand, but the OR operator is almost always used in constructors where I set private members based on the arguments provided.

    config = {
    defaultValue : ‘my default value’
    }

    function instance(value, parentNode){
    this.value = value || config.defaultValue;
    this.parentNode = parentNode || document.getElementsByTagName(‘BODY’)[0];
    }

  • http://erik.eae.net Erik Arvidsson

    I would second Micha here. Or is commonly suitable for assignments. These thing can be a bit hard to understand if used in more complex cases.

  • http://www.robertnyman.com Robert Nyman

    When it comes to ternary expressions, I agree. Depends on how complex it is.
    The example in your post is ok, I think, but when you have more options it’s not the best way to go.

    For example, this is not desirable for me, if...else would be better in this case:

    var el = (e.target)? (bIsTuesday)? e.target : e.keyCode : e.srcElement;

  • http://erik.eae.net Erik Arvidsson

    Well, you usually use || if one of the alternative objects are avaialable. Ternary expression are useful but for different reasons. I agree that nesting ?: is usually a bad idea.

  • http://www.wdonline.com Jerem

    It usually gets me in trouble (or I’m told it’s not proper)… but if it saves me lines, I run with it. I have a line like this in one of my scripts:

    this.node = oNode || false;
    this.value = sValue || (this.node && this.node.text) || false;

    I don’t have a problem reading it, but that’s just me.

  • http://www.wdonline.com Jeremy

    And I can’t even type my own effin’ name. hahaha

  • Patrick Corcoran

    I did some basic performance tests iterating over 1,000,000 iterations of each syntax, and no performance difference between the two syntaxes was noticeable.

    I would guess from this that they are identical after “compilation”.

  • http://www.unitedscripters.com/ Alberto

    var el = e.target || e.srcElement;

    Ternary still looks clearer. Yet this one has always had its appeal.
    The only thing I always wondered about these approaches is: has anyone found a reliable way to benchamrk the both of them and see what type of performance gain there can be- if any?
    That is, without having to wait 2 hours (which no js interpreter would allow) before having a meaningful difference.

  • http://erik.eae.net Erik Arvidsson

    I don’t think you need to care about the performance here. The || operator should be slightly faster but compared to the slow DOM code browsers have it is just a drop in the ocean.

    The expressions are not identical because that would break semantics. When using the ternary operator the expression is executed twice. Here is a test case that shows that they are different:

    var c = 0;
    function f() {
    return c++;
    }

    var a = f() || ‘a’; // ‘a’
    var b = f() || ‘b’; // 1

    // reset
    c = 0;

    a = f() ? f() : ‘a’; // ‘a’
    b = f() ? f() : ‘b’; // 2

  • Theodor Zoulias

    try {
    a
    } catch(e) {
    alert(e)
    }

    IE: [object Error]
    FF: ReferenceError: a is not defined
    ——————————————
    try {
    throw ‘my error’
    } catch(e) {
    alert(e.message)
    }

    IE: undefined
    FF: undefined
    ——————————————
    try {
    a
    } catch(e) {
    alert(e.description || e.message || e)
    }

    IE: ‘a’ is undefined
    FF: a in not defined

  • http://erik.eae.net Erik Arvidsson

    Theodor: I’m not sure what that was an answer to but those are some interesting code snippets. Here is another one:

    try {
    throw new Error(“my error”); // new can be omitted
    } catch(e) {
    alert(e.message)
    }

    IE: my error
    FF: my error
    Opera: my error

  • Theodor Zoulias

    Interesting. I’ve only used Error constructor server-side, with JScript. But is cross-browser supported? It seems that IE5 knows nothing about property “message” and returns undefined. :) My purpose was just to give an example where OR operator becomes handy. Saves bytes too!