2013-02-20 7 views
39

Enumerabilität ist eines der drei Attribute einer Eigenschaft: Schreibbarkeit, Aufzählbarkeit und Konfigurierbarkeit. Meine Fragen sind:Welche Vorteile bietet es, Eigenschaften nicht aufzählbar zu machen?

  • Was sind die Vorteile, Eigenschaften in JavaScript nicht aufzählbar zu machen? Ich weiß, dass wir das Eigentum verstecken, indem wir sie nicht aufzählbar machen, aber was ist der Vorteil des Verbergens von Immobilien?
  • Können wir auf nicht aufzählbare Eigenschaften zugreifen? Wenn ja, was bringt es, sie nicht aufzählbar zu machen?
  • Sind alle vordefinierten Eigenschaften von Objekten als nicht aufzählbar definiert? Wie im Fall der Array-Eigenschaften pop und push, die nicht aufzählbar sind?
+1

Ich denke, der Hauptvorteil 'für in' zu machen, ist Schleifen sicher - das Objekt wird nicht angezeigt, wenn über das Objekt iterieren. Vielleicht vergesse ich, was Aufzählbarkeit tut ... – Ian

+2

Related: [Was sind die Vorteile und Gefahren des Hinzufügens von Methoden zu Object.prototype in Javascript?] (Http://stackoverflow.com/questions/3832617/what-are-the Vorteile-und-Gefahren-von-Hinzufügen-Methoden-zu-Objekt-Prototyp-in-Javas? Rq = 1). –

Antwort

35

ich der größte Vorteil denke, ist in der Lage sein, um zu steuern, was beim Auflisten der Eigenschaften eines Objekts angezeigt wird, z. B. for in oder Object.keys().

MDN erklärt es gut mit Object.defineProperty: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty

So normal, wenn die Menschen, ein Verfahren zu Object, wie ein polyfill für einige Verfahren nicht in alten Browsern unterstützt hinzufügen wollen, sie die .prototype ändern. Aber das macht die Eigenschaft aufzählbar und vermasselt, was in Schleifen/Schlüssel-Sammlung zurückgegeben wird (ohne .hasOwnProperty ... die nicht jeder verwendet).

Anstatt also so etwas wie:

Object.prototype.myMethod = function() { 
    alert("Ahh"); 
}; 

könnten Sie Object.defineProperty verwenden explizit zu sagen, dass es nicht zählbare zu haben:

Object.defineProperty(Object.prototype, 'myMethod', { 
    value: function() { 
     alert("Ahh"); 
    }, 
    enumerable: false 
}); 

So zum Beispiel, wenn Sie verwenden for (var key in obj) „myMethod "wird kein aufgezähltes Objekt sein, und Sie müssen sich keine Sorgen über die Verwendung von .hasOwnProperty machen. Das Hauptproblem dabei ist, dass einige Browser es natürlich nicht unterstützen: http://kangax.github.com/es5-compat-table/ und dass nicht alle Bibliotheken/Code es benutzen, so dass man sich nicht immer auf externe Bibliotheken/Code verlassen kann, um es richtig und ständig zu benutzen.

Sie können jederzeit auf eine nicht aufzählbare Eigenschaft zugreifen, sie wird nur beim Aufzählen der Objekteigenschaften angezeigt - das ist der Hauptpunkt.

Und ich glaube, dass alle "vordefinierten" Eigenschaften von Objekten nicht aufzählbar sind. Damit meine ich eigentlich nur native Eigenschaften, die nicht unbedingt geerbt oder erzeugt werden müssen. Also mit Ihrem Beispiel, pop und push wird nicht über aufgezählt werden, aber Array.prototype.indexOf wird sein, wenn es als ein Polyfill auf einem alten Browser erstellt wird, der diese Methode nicht unterstützt ...was natürlich vermieden werden kann, indem ich Object.defineProperty wie mein Beispiel oben verwende. Ein anderes Beispiel ist die length-Eigenschaft, die nicht überzählig ist.

Hier ist ein Beispiel im allgemeinen: http://jsfiddle.net/aHJ3g/

Die Verwendung des Wortes Object.keys ist wichtig: „Gibt ein Array einer eigenen enumerable Eigenschaften des gegebenen Objekts in der gleichen Größenordnung wie die von einem for-in Schleife (die Differenz zur Verfügung gestellt dass eine for-in Schleife auch Eigenschaften in der Prototypkette aufzählt). " - von MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

2
  • Indem die Eigenschaft nicht-zählbare Sie immer noch darauf zugreifen können. Wenn Sie jedoch eine For-In-Schleife für das Objekt anwenden, wird die nicht-aufzählbare Eigenschaft nicht iteriert.
  • Siehe ersten Punkt
  • Geerbte Eigenschaften von integrierten Objekten (wie push, pop, toString ...) ist nicht zählbare

    var o = {a:1, b:2, c:3} // a,b,c are enumerable properties 
    o.propertyIsEnumerable("toString") // returns false, because it is a inherited property 
    for(p in o) console.log(p); // this loop will print a,b and c but not toString or other inherited properies 
    
+2

Ich glaube, der dritte Punkt ist falsch. Vererbte Eigenschaften sind sicherlich genauso aufzählbar wie alle anderen ... 'var x = {a: 1}; var y = Objekt.erstellen (x); y.b = 2; for (Name in y) {console.log (Name, y [Name]);} 'ergibt' b 2' und 'a 1'. –

+0

Sie haben Recht! Vererbte Eigenschaften sind ebenfalls aufzählbar. Wenn Sie nur eigene und aufzählbare Eigenschaften haben möchten, verwenden Sie Object.keys(). – daniatic

11

Ein anderer Hauptvorteil, wie ich es sehe, ist, dass es verhindert, dass private Eigenschaften eines Objekts den öffentlichen Namensraum verschmutzen.

Angenommen, Sie haben eine leistungsstarke Bibliothek namens Cosmos erstellt und veröffentlicht. Der Benutzer löst den Knoten Interpreter und erstellt eine neue Instanz durch den Konstruktor aufrufen:

var Cosmos = require('Cosmos'); 
var cosmos = new Cosmos('my empire'); 

nun der Benutzer einfach Typen cosmos und Pressen eingeben, um zu sehen, welche öffentliche API unterstützt wird. Welche der beiden soll der Benutzer sehen?

{ name: 'my empire', 
    grow: [Function: grow], 
    addStar: [Function: addStar], 
    beautify: [Function: beautify], 
    implode: [Function: implode], 
    destroy: [Function: destroy] } 

ODER

{ _age: 25000, 
    _size: 35000, 
    _destroyed: false, 
    name: 'my empire', 
    _numStars: 200, 
    _init: [Function: _init], 
    grow: [Function: grow], 
    _grow: [Function: _grow], 
    addStar: [Function: addStar], 
    _checkStatus: [Function: _checkStatus], 
    beautify: [Function: beautify], 
    implode: [Function: implode], 
    destroy: [Function: destroy] } 
+3

nicht aufzählbare Eigenschaften sind noch öffentlich und verschmutzen immer noch den Namensraum. Wenn Sie private Eigenschaften haben wollen, brauchen Sie eine Schließung. – Matthew

+4

Ich upvoted sowohl die Antwort als auch den kritischen Kommentar. Die Kritik des Kommentars scheint mir gültig zu sein, daher mag die Verwendung von "öffentlich" und "privat" möglicherweise nicht optimal sein. Ich denke jedoch, dass der Punkt der Antwort immer noch hilfreich ist (zumindest für mich), weil er zeigt, wie die Aufzählbarkeit dem Bibliotheksbenutzer helfen kann, leichter zu sehen, was der Bibliotheksautor für den Bibliotheksbenutzer leicht verwenden wollte (z. B. bitte ' wachsen und nicht "wachsen", auch wenn beide technisch noch öffentlich sind. –

Verwandte Themen