Its each method
代码如下: var each = _.each = _.forEach = function(obj, iterator, context) { if (obj == null) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === +obj.length) { for (var i = 0, l = obj.length; i < l; i++) { if (iterator.call(context, obj[i], i, obj) === breaker) return; } } else { for (var key in obj) { if (_.has(obj, key)) { if (iterator.call(context, obj[key], key, obj) === breaker) return; } } } };
There is a sentence in this method
if (obj.length === +obj.length)
This sentence is equivalent to
if (typeof obj.length === 'number')
, which is used to determine whether the element is of numeric type. typeof and Object.prototype.toString are common ways of writing. The last one is uncommon and difficult for ordinary people to understand.
Some libraries have tool functions for type judgment, such as
代码如下: function isNumber1(a){ return typeof a === 'number' }
or you can use Object.prototype.toString
代码如下: function isNumber2(a) { return Object.prototype.toString.call(a) === '[object Number]' }
to change it to this way of writing
代码如下: function isNumber3(a){ return a === +a }
Use various types to test
代码如下: var arr = ['1', true, false, undefined, null, {}, [], 1] for (var i=0; i<arr.length; i++) { console.log(isNumber3(arr[i])) }
The result is only the last one of the array item is true. That is, only the numeric type a === +a is true.
Why not use typeof? Because string comparison theoretically needs to traverse all characters, and the performance is directly proportional to the length of the string.