2

I was looking at the implementation of indexOf from MDN. This is what I'm curious about:

n = (n > 0 || -1) * Math.floor(Math.abs(n));

It seems to me that (n > 0 || -1) is going to evaluate to true or false, but then it's being multiplied?

In case the link ever breaks, this is the indexOf implementation from MDN:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this == null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 1) {
            n = Number(arguments[1]);
            if (n != n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n != 0 && n != Infinity && n != -Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}
  • 2
    Read more about the JavaScript `||` operator. It is not the same as C. Also, read about type conversions. They are also not the same as C. – Raymond Chen May 07 '13 at 14:38
  • Also, you need to fix your title. It is unlikely to be useful to future visitors with the same question. – Raymond Chen May 07 '13 at 14:45
  • @RaymondChen What would you recommend? –  May 07 '13 at 14:46
  • How about "Why is (n>0 || -1) used in multiplication in the implementation of indexOf?" – JJJ May 07 '13 at 14:47
  • possible duplicate of [Javascript logical operators and results](http://stackoverflow.com/questions/11283366/javascript-logical-operators-and-results) – Raymond Chen May 07 '13 at 15:03

3 Answers3

3

It seems to me that (n > 0 || -1) is going to evaluate to true or false

Nope. The || operator in JavaScript is curiously powerful, if n is <= 0, that expression results in -1, not false.

If n > 0, that expression will indeed yield true, and yes, they really are multiplying true by a number. That's okay (I wouldn't do it, but it's allowed), true will get automatically coerced into a number (1), because both sides of a * are coerced to numbers before the multiplication. The conversion of various types to numbers is in Section 9.3 of the spec.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

first:

(n > 0 || -1)

Which goes in the following order:

  n > 0  // if true it stops here and -1 is not evaluated.
  -1

Then it tries to multiply either

   true * Math.floor(Math.abs(n))
   or
   -1 * Math.floor(Math.abs(n))

And finally it either stores:

n = 1 * Math.floor(Math.abs(n))
or 
n = -1 * Math.floor(Math.abs(n))
fmsf
  • 36,317
  • 49
  • 147
  • 195
0

If the first part is false then it would multiply by -1, otherwise it would multiply by 1. The OR operator returns the right hand side of the expression if the left hand side is "falsy"

Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100