2009-07-10 6 views
40

lo que permite decir que he añadido algunos métodos de prototipo a la clase Array:Javascript: ¿ocultar los métodos de prototipos en for loop?



Array.prototype.containsKey = function(obj) { 
    for(var key in this) 
     if (key == obj) return true; 
    return false; 
} 

Array.prototype.containsValue = function(obj) { 
    for(var key in this) 
     if (this[key] == obj) return true; 
    return false; 
} 

continuación, se crea una matriz asociativa y de intento de bucle a través de él de las teclas:



var arr = new Array(); 
arr['One'] = 1; 
arr['Two'] = 2; 
arr['Three'] = 3; 

for(var key in arr) 
    alert(key); 

Esto devuelve cinco elementos:

 
    -One 
    -Two 
    -Three 
    -containsKey 
    -containsValue 

pero quiero (¿espera?) Solo tres. ¿Me estoy acercando a esto mal? ¿Hay alguna manera de "ocultar" los métodos prototipos? o debería estar haciendo algo diferente?

+0

Ver también [esta respuesta] (http://stackoverflow.com/a/13296897/1048572) – Bergi

Respuesta

42

Puede utilizar el método de JavaScript hasOwnProperty para lograr esto en el bucle, como esto:

for(var key in arr) { 
    if (arr.hasOwnProperty(key)) { 
     ... 
    } 
} 

Referencia: This YUI blog article.

+12

Irónicamente me encontré con este problema al tratar de crear una versión más corta de hasOwnProperty 'Object.prototype.has = Object.prototype .hasOwnProperty' – Moss

2

usted puede hacer esto:

for(var key in arr) 
{ 
    if (typeof(arr[key]) == "function") 
     continue; 
    alert(key); 
} 

Pero eso es una solución de mala calidad

4

Javascript no admite matrices asociativas su forma de pensar que lo hacen. http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

for (var i en .. recupera todas las propiedades de un objeto (un array es un objeto más) por lo que se está viendo los otros objetos que haya un prototipo a ella.

Como el artículo sugiere que debe utilizar un objeto:.


var assoc = {'One' : 1, 'Two' : 2}; 
assoc['Three'] = 3; 

for(var key in assoc) 
    alert(key+' => '+assoc[key]); 
0

para la iteración de alta resolución sobre las matrices de JavaScript, utilice un bucle for o while Nicholas Zakas analiza las opciones más-performant para iterar sobre matrices en su Tech Talk Speed Up Your JavaScript

Su mejor apuesta es probablemente algo como esto:

for (var i = collection.length - 1; i >= 0; i--) { 
    if (obj == collection[i]) return true; 
} 

Este enfoque se peform mejor por varias razones:

  • Sólo una única variable local se asigna
  • propiedad de la colección length solo se accede una vez, en la inicialización del ciclo
  • Cada iteración, un local se compara con una constante (i >= 0) ANUNCIO a otra variable
+1

No se puede iterar así dado el modo en que ha utilizado la matriz ya que no ha usado números como claves para que la colección [1] no exista cuando la haya llamado colección ['uno'] – rezzif

38

Puede lograr el resultado deseado desde el otro extremo al hacer que los métodos de prototipo no enumerables:

Object.defineProperty(Array.prototype, "containsKey", { 
    enumerable: false, 
    value: function(obj) { 
     for(var key in this) 
     if (key == obj) return true; 
     return false; 
    } 
}); 

Esto generalmente funciona mejor si usted tiene control sobre definiciones de métodos, y en particular, si no tiene control sobre cómo su código será llamado por otras personas, que es una suposición común en el desarrollo del código de la biblioteca.

+3

Esto es particularmente útil cuando no tiene control sobre el código que está en bucle. – Aurimas

+0

desafortunadamente defineProperty solo funciona para los elementos DOM para IE8 http://kangax.github.io/compat-table/es5/#define-property-ie-note –

+2

Esto es mucho más elegante que comprobar hasOwnProperty en cada ciclo. Para los navegadores más antiguos, puede implementar su propia implementación, como esta, por ejemplo: https://github.com/inexorabletash/polyfill/blob/master/es5.js#L71 – ZolaKt