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

1229Re: [jslint] && as flow control

Expand Messages
  • Michael Mikowski
    Mar 12, 2010
      If you use jslint and have read "the good parts," you certainly should be aware of type coercion. 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');

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

      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." Type coercion errors are discussed on page 121.

      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.

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

      Michael Mikowski wrote:
      > Probably because type coercion is considered sloppy programming in any
      > language. In this case, foo[0] test for "truthiness" which means the
      > value must be /true/, or non-zero, or a non-empty string, or defined
      > (maybe, unless it is autovivified) , or ... and the list goes on.

      There's no Autovivification in JS, maybe you were thinking of Perl.
      Anyway, type coercion can't be the reason for the JSLint error, or this
      construct would pass:

      typeof foo[0] == "undefined" && fop = foo.shift();

      Type coercion can happen with or without this use of '&&' for flow
      control, same as with the more usual if/else. I rather suspect there are
      two other problems with this statement. The first is the assignment: if
      you wrap it in parentheses, JSLint will parse it correctly and issue a
      different warning:

      foo[0] && (fop = foo.shift()) ;

      "Expected an assignment or function call and instead saw an expression."

      Expression statements are valid in ECMAScript, but they aren't part of
      DC's Good Parts. I don't have the book at home, so I can't look up the
      rationale for that right now; maybe someone else can.

      > Can you name all "truthy" or "falsy" conditions off the top of your
      > head? How many on your team can?

      It's impossible to name all truthy values, but the falsy ones should be
      known to every JS developer. There aren't that many: null, undefined, 0,
      false, '', and NaN.

      I agree that it's harder to remember all the different rules for type
      coercion. For example:

      var x = new String("");

      // this prints "true"
      if (x) { console.log( "true"); }

      // and so does this, go figure...
      if (x == false) { console.log( "true"); }

      There are many other confusing examples like this.


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