2009-07-10 3 views
40

können also sagen, ich habe einige Prototyp Methoden der Array-Klasse hinzugefügt:Javascript: Verbergen von Prototyp-Methoden in for-Schleife?



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; 
} 

dann erstelle ich ein assoziatives Array und versuchen, Schleife durch sie die Tasten:



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

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

diese fünf Elemente zurückgibt:

 
    -One 
    -Two 
    -Three 
    -containsKey 
    -containsValue 

aber ich will (erwarten?) Nur drei. Komme ich mir das falsch? Gibt es eine Möglichkeit, die prototypischen Methoden zu "verstecken"? oder sollte ich etwas anders machen?

+0

Siehe auch [diese Antwort] (http://stackoverflow.com/a/13296897/1048572) – Bergi

Antwort

42

können Sie JavaScripts hasOwnProperty Methode verwenden, um dies in der Schleife zu erreichen, wie folgt aus:

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

Referenz: This YUI blog article.

+12

Ironischerweise stieß ich auf dieses Problem, indem ich versuchte, eine kürzere Version von hasOwnProperty 'Object.prototype.has = Object.prototype zu erstellen .hasOwnProperty' – Moss

2

Sie dies tun könnte:

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

Aber das ist eine schlampige Abhilfe

4

Javascript nicht assoziative Arrays, die Art und Weise unterstützt Sie denken, sie tun. http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

for (var i in .. bekommt alle Eigenschaften eines Objektes (ein Array nur ein weiteres Objekt ist), weshalb Sie die anderen Objekte sind zu sehen Sie es prototypisiert haben.

Wie der Artikel legt nahe Sie ein Objekt verwenden soll.


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

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

für High-Performance-Iteration über JavaScript-Arrays, verwendet entweder eine for oder while Schleife Nicholas Zakas die meisten performanten Optionen für die Iteration über Arrays in seinem Tech Talk diskutiert Speed Up Your JavaScript

Ihre beste Wette ist wahrscheinlich so etwas wie folgt aus:

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

Dieser Ansatz am besten für ein paar Gründe peform werden:

  • nur eine einzige lokale Variable
  • Die length Eigentum der Sammlung zugeordnet ist wird nur einmal aufgerufen, bei der Initialisierung der Schleife
  • Bei jeder Iteration wird ein Local mit einer Konstanten (i >= 0) verglichen

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

    Dies funktioniert in der Regel besser, wenn Sie die Kontrolle über Methodendefinitionen haben, insbesondere: Anzeige von einer anderen Variablen

+1

Sie können nicht so iterieren, da er das Array benutzt hat, da er keine Zahlen als Schlüssel verwendet hat, so dass die Sammlung [1] nicht existiert, wenn er sie als Sammlung ['one'] – rezzif

38

Sie können, indem die Prototyp Methoden nicht zählbare gewünschtes Ergebnis vom anderen Ende erreichen wenn Sie keine Kontrolle darüber haben, wie Ihr Code von anderen Personen aufgerufen wird, was eine häufige Annahme in der Entwicklung von Bibliothekscodes ist.

+3

bezeichnet hat Dies ist besonders nützlich, wenn Sie keine Kontrolle über den Code haben, der eine Schleife bildet. – Aurimas

+0

leider defineProperty funktioniert nur für DOM-Elemente für IE8 http://kangax.github.io/compat-table/es5/#define-property-ie--note –

+2

Dies ist so viel eleganter als die Überprüfung hasOwnProperty in jeder Schleife. Für ältere Browser können Sie Ihre eigene Implementierung, wie diese zum Beispiel rollen: https://github.com/inexoretetash/polyfill/blob/master/es5.js#L71 – ZolaKt

Verwandte Themen