Loading ...
Sorry, an error occurred while loading the content.

1230Re: [jslint] && as flow control

Expand Messages
  • Stefan Weiss
    Mar 12, 2010
    • 0 Attachment
      Michael Mikowski wrote:
      > Using && and || for flow control doesn't
      > require coercion but it certainly encourages it. Writing this:
      >
      > ary[0] && obj['key'] && bar && alert('guantlet passed');
      >
      > gives us 3 type coercions, roughly equivalent to:
      >
      > ( ary[0] == true ) && ( obj['key'] == true ) && ( bar == true ) &&
      > alert('gauntlet passed');

      And the exact same thing happens if you don't use expression statements:

      if (ary[0] && obj['key'] && bar) {
      alert('guantlet passed');
      }

      Expression statements and type coercion are not directly related; it's
      the "&&" operator which forces boolean context. If you don't want the
      value of "ary[0]" or "bar" or whatever evaluated in boolean context,
      then don't use "&&", or do an explicit comparison with the correct type.

      In many situations, like when the possible contents of "ary" are known,
      or when all falsy values are to be excluded, it's more concise to use
      "&&". Nothing wrong with that, if you know what you're doing - there are
      tens of valid examples in the JSLint source itself.

      > As for "(maybe, unless it is autovivified)," how many people need to
      > look that up? Because js does "pretend" keys exist when looking up an
      > array or object value. To wit:
      >
      > // false if ary[0] does not exist OR if it does exist and the value is
      > not "truthy"
      > ary[0] ....
      >
      > // true only if array has element 0
      > ary.hasOwnProperty(0) ...
      >
      > And before anyone asks, the latest version of firebug (1.5.2) with
      > STRICT warnings doesn't show a thing if you address uninitialized ary[x]
      > where x can be any numerical value (it does catch object keys, however).

      That doesn't prove that ary[0] is autovivified, only that Mozilla
      decided not to issue a strict warning when a nonexistent array index is
      accessed. If there was any autovivification, the property "0" would
      exist after an attempt to read it. This is not the case:

      var ary = [];
      console.log(ary[0]); // "undefined"
      for (var prop in ary) { console.log(prop); } // nothing

      (Aside, I think the "strict" warnings in Firefox are way over the top. I
      don't know any other developer who pays attention to them. Even the
      JSLint script triggers numerous warnings.)

      > The Good Parts doesn't go into depth about it, but on page 120 when
      > explaining jslint, it states: "An expression statement is expected to be
      > an assignment, a function/method call, or delete. All other expression
      > statements are considered errors."

      Thanks for checking.
      I guess the OP was hoping for more of an explanation.

      By the way, I can think of a couple more expression statements that are
      accepted by JSLint: pre/postfix increment and decrement, bit shifting,
      and '"use strict";' (the former two are not part of the Good Parts, and
      there are options to disallow them).

      > In the end, using expression statements can give you all the terseness
      > of a regular expression without the precision and power. It can be the
      > worst of both worlds. They don't pass our code reviews.

      I don't understand the comparison with regular expressions. Anyway, I'm
      not in any way advocating the use of these "flow control" expression
      statements. I happen to like them (but then, I also like Perl), others
      don't, no big deal. They are easy enough to avoid when I'm writing
      JSLint compatible scripts.


      stefan
    • Show all 12 messages in this topic