2012-02-17 17 views
5

Ya hay una respuesta publicada en la prueba, que se puede encontrar here, pero no puedo entender por qué esa respuesta es correcta.Tiene problemas para entender una prueba de reflexión en Javascript Koans

La parte de la test que me está dando problemas es:

var keys = []; 
var fruits = ['apple', 'orange']; 
for(propertyName in fruits) { 
    keys.push(propertyName); 
} 
ok(keys.equalTo(['__', '__', '__']), 'what are the properties of the array?'); 

El (aparentemente) respuesta correcta, como se señala en la pregunta vinculado anteriormente es

ok(keys.equalTo(['0', '1', 'fruits.prototype'), 'what are the properties of the array?'); 

Probé la inserción de la respuesta - corrigió el error de sintaxis - y mi prueba aún falla.

En el mismo archivo de prueba, otra prueba es casi idéntica y la respuesta es lo que yo esperaba que fuera:

test("property enumeration", function() { 
    var keys = []; 
    var values = []; 
    var person = {name: 'Amory Blaine', age: 102, unemployed: true}; 
    for(propertyName in person) { 
     keys.push(propertyName); 
     values.push(person[propertyName]); 
    } 
    ok(keys.equalTo(['name','age','unemployed']), 'what are the property names of the object?'); 
    ok(values.equalTo(['Amory Blaine',102,true]), 'what are the property values of the object?'); 
}); 

La única diferencia que veo entre estas dos pruebas es que la segunda está utilizando un objeto en lugar de una matriz.

Ejecuté el código desde la primera prueba por sí mismo (fuera del marco de prueba de la unidad) y obtuve el valor de las claves, que se mostró como ["0","1"] - lo que esperaría. ¿Dónde está este tercer valor oculto y cómo puedo acceder a él?

Por lo tanto, supongo que en última instancia, tengo dos preguntas:

  1. ¿Por qué la respuesta de la otra pregunta que no trabaja para mí?
  2. ¿Qué tiene de diferente la primera prueba y la segunda?

Respuesta

2

Descargo de responsabilidad: Estoy bastante seguro de que esto es correcto, pero no me he molestado en probarlo. ¿Podría probar mi respuesta, ya que tiene las pruebas en ejecución?

Al mirar los archivos en GitHub, hay un script de ayuda llamado koan.js. Supongo que se carga antes de las pruebas porque soy demasiado perezoso para ejecutarlas yo mismo: P. (Está en el directorio support.)

En este archivo, hay un método llamado equalTo definido en todas las matrices:

Array.prototype.equalTo = function(compareTo) { ... } 

para que las respuestas a sus preguntas:

  1. Debido a la respuesta a la otra pregunta estaba mal. Completamente equivocado. Etc.
  2. Porque el método se define en Array en lugar de Object.

Parece un poco decepcionante.

Si define una función como esta en el prototipo, todas las matrices la heredarán. Intente definir algo así en la consola y luego evalúe [].equalTo.Y luego, para más diversión, intente algo como:

for (x in []) console.log(x) 

Dado que se define este método en el prototipo, se repite el bucle sobre él también. Entonces la respuesta es que la prueba es probablemente 0, 1, 'equalTo'. Sin embargo, si utiliza el bucle for con la verificación hasOwnProperty, naturalmente no repetirá el método.

Esto es realmente una lección objetiva sobre no usar for in para iterar sobre matrices :). Nunca se sabe lo que va a colarse ... Casualmente, esta es la razón por la que prototype.js cayó en desgracia a pesar de ser realmente un buen marco.

+0

Pero si lanza un ['hasOwnProperty'] (https://developer.mozilla.org/es/JavaScript/Reference/Global_Objects/Object/HasOwnProperty) en la mezcla, puede solucionar los problemas del prototipo. –

+0

@muistooshort: Aún tiene problemas si alguien agrega alguna otra propiedad a su matriz: 'a = []; a.alive = falso; '. Creo que solo usar un bucle 'for' normal o, mucho mejor, una función apropiada de orden superior (' forEach', 'map',' filter', 'reduce' ... etc) es el mejor enfoque. –

+0

No estoy en desacuerdo contigo, usar 'for ... in' para una matriz no tiene mucho sentido, es más una cuestión de usar' for ... in' sin incluir una comprobación 'hasOwnProperty' casi siempre siendo un error si debe usar 'for ... in' o no. –

Cuestiones relacionadas