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

1231Re: [jslint] && as flow control

Expand Messages
  • Michael Mikowski
    Mar 12, 2010
    • 0 Attachment
      From: Stefan Weiss <weiss@...>
      To: jslint_com@yahoogroups.com
      Sent: Fri, March 12, 2010 6:08:23 PM
      Subject: Re: [jslint] && as flow control

      > 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.

      I think we agree. This is our example, but written for better precision:

      if ( arg.hasOwnProperty(0) && obj.hasOwnProperty(0) && bar === true ){...}

      > 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.

      True, js does not autovivify. But during comparisons it acts like it does.
      So if one is using "if (ary[x])" to test if an element exists, they are
      in for an unpleasant surprise when it comes time to debug.

      I wasn't advocating the idea of using strict warnings either, just illustrating
      that even with the strictest warnings there is no way to tell if an array value
      is uninitialized unless you directly check for it.

      > I don't understand the comparison with regular expressions.

      Don't get me wrong - I love regular expressions and use them all the time.
      They can be very precise and powerful. It is their terseness that scares
      a lot of people, and makes them hard to debug sometimes.
      Flow controls like 'ary[0] && obj['key'] && bar && ...'
      are also terse, but lack precision, so they can be even more difficult to debug.

      > 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.

      Never say never; everything has its place :) Oh, and I'm a big fan of
      Perl too :)




      ________________________________
      From: Stefan Weiss <weiss@...>
      To: jslint_com@yahoogroups.com
      Sent: Fri, March 12, 2010 6:08:23 PM
      Subject: Re: [jslint] && as flow control


      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



      [Non-text portions of this message have been removed]
    • Show all 12 messages in this topic