2011-08-01 11 views
6

Pregunta sobre la implementación de la función "cada" que encontré en el código fuente de underscore.js (fuente a continuación).cada implementación en la biblioteca underscore.js

En primer lugar, alguien podría explicar qué es lo que la línea "else if (obj.length === + obj.length)" está buscando.

En segundo lugar, ¿alguien podría explicar por qué se usa hasOwnProperty.call (obj, key), en oposición a obj.hasOwnProperty? ¿Es porque el obj aprobado no puede implementar hasOwnProperty (que pensé que todos los objetos javascript)

se apreciaron las ideas. Gracias.

// 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; 
     } 
     } 
    } 
    }; 
+0

'+ obj.length' es el operador javascript unary add. ver: http://xkr.us/articles/javascript/unary-add/ – mikeycgto

+0

Entonces, ¿la declaración es un cheque para asegurarse de que la propiedad de longitud de obj es en realidad un número? – user772110

+0

la declaración '+ obj.length' convierte' obj.length' a un número – mikeycgto

Respuesta

5

Este:

+obj.length 

... va a hacer una conversión ToNumber en el valor de length.

Parece que se están asegurando de que length haga referencia a un número haciendo la conversión a Número y verificando que sigue siendo el mismo número después de la conversión.

Si es así, suponen que se trata de una matriz, o al menos un objeto parecido a una matriz para la iteración.

De lo contrario, suponen que se desea enumerar todos los pares de valores clave.

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 

supuesto, usted podría tener un objeto con una propiedad length que es un número primitivo, pero aún así la intención de enumerar las propiedades.

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 
Cuestiones relacionadas