6

I was perusing the underscore.js annotated source when I encountered this:

if (obj.length === +obj.length) {...}

I now know from this stackoverflow question that the plus sign (+) operator returns the numeric representation of the object.

That said, obj.length returns a number. When would obj.length not be equal to +obj.length?

Community
  • 1
  • 1
doremi
  • 14,921
  • 30
  • 93
  • 148
  • 5
    it ensures that the length holds an actual number and not a string representing a number.. (*because it uses `===` which checks type as well*). This way it increases protection against passing it a random object that happens to have a `length` property. – Gabriele Petrioli Jan 25 '14 at 23:35

2 Answers2

5

The === operator does not make any typecast when it checks, so different types of data will immediately return false even if '5' == 5. The + as you said typecasts the object into number. If you typecast a number into a number, it is still a number, so you basically check if your object.length exists and is a number. Values like undefined, NaN, null, string and others will return false. You are not sure what happens with obj, so you have to check...

Theofilos Mouratidis
  • 1,146
  • 12
  • 32
1

When, for example:

var obj = {
    0: 'first',
    length: '1'
};

alert(obj.length === +obj.length);

Underscore's each is a generic, therefore can work with other objects other than an array. Just like ECMA5 forEach

The forEach function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the forEach function can be applied successfully to a host object is implementation-dependent.

So underscore are checking the validity of an object's length property. And they deem an object arrayLike, for that method of iteration, only if the object's length returns a number which is not NaN, and is certainly not a string. So in my above example, obj would fall through to their keys iteration, if there is no native/polyfilled forEach.

Xotic750
  • 22,914
  • 8
  • 57
  • 79