开发者

each implementation in the underscore.js library

开发者 https://www.devze.com 2023-03-24 09:05 出处:网络
Question about the implementation of the \"each\" function I found in the underscore.js source code (source below).

Question about the implementation of the "each" function I found in the underscore.js source code (source below).

First, could someone explain what the line "else if (obj.length === +obj.length) " is checking for.

Second, could someone explain why hasOwnProperty.call(obj, key) is used, as opposed to ob开发者_Go百科j.hasOwnProperty? Is it because the passed in obj may not implement hasOwnProperty (which I thought every javascript object did)

any insights appreciated. Thanks.

  // The cornerstone, an `each` implementation, aka `forEach`.
  // Handles objects with the built-in `forEach`, arrays, and raw objects.
  // Delegates to **ECMAScript 5**'s native `forEach` if available.

  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 (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;

      }
    } else {
      for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) {
          if (iterator.call(context, obj[key], key, obj) === breaker) return;
        }
      }
    }
  };


This:

+obj.length

...will do a toNumber conversion on the value of length.

It appears as though they're making sure that length references a number by doing the toNumber conversion, and verifying that it's still the same number after the conversion.

If so, they assume that it is an Array, or at least an Array-like object for iteration.

If not, they assume that enumeration of all key value pairs is desired.

var obj = {
     length:null,
     someprop:'some value'
};

obj.length === +obj.length; // false, so do the enumeration
var obj = {
    length: 2,
    "0":'some value',
    "1":'some other value'
};

obj.length === +obj.length;  // true, not an actual Array, 
                             //     but iteration is still probably wanted

Of course you could have an object with a length property that is a primitive number, but still intend to enumerate the properties.

var obj = {
    length: 2,
    "prop1":'some value',
    "prop2":'some other value'
};

obj.length === +obj.length;  // true, it will iterate, but it would
                             //           seem that enumeration is intended
0

精彩评论

暂无评论...
验证码 换一张
取 消