Was bedeutet Aufzählung?

151

Ich wurde zu MDNs for..in-Seite geleitet, als dort stand: "for..in iteriert über die aufzählbaren Eigenschaften eines Objekts."

Dann ging ich zur Seite Aufzählbarkeit und Besitz von Eigenschaften, auf der stand: "Aufzählbare Eigenschaften sind diejenigen, die von einer for..in-Schleife iteriert werden können."

Das Wörterbuch definiert enumerable als zählbar, aber ich kann mir nicht wirklich vorstellen, was das bedeutet. Könnte ich ein Beispiel dafür bekommen, dass etwas aufzählbar ist?

Patrick
quelle
Verstehst du was for-inmacht?
Aus den Antworten, die ich für ... erhalten habe, können alle aufzählbaren Eigenschaften eines Objekts zur Verwendung mit der for-Anweisung verfügbar sein
Patrick
6
Die einfachste Bedeutung ist: ob eine Eigenschaft von einer for inSchleife erzeugt wird oder nicht (für diejenigen, die die Details nicht wissen wollen oder sich einfach nicht darum kümmern;))
Tomasz Racia

Antworten:

158

Eine aufzählbare Eigenschaft kann in for..inSchleifen (und einer ähnlichen Iteration von Eigenschaften wie Object.keys()) aufgenommen und besucht werden .

Wenn eine Eigenschaft nicht als aufzählbar identifiziert wird, ignoriert die Schleife, dass sie sich innerhalb des Objekts befindet.

var obj = { key: 'val' };

console.log('toString' in obj); // true
console.log(typeof obj.toString); // "function"

for (var key in obj)
    console.log(key); // "key"

Eine Eigenschaft wird durch ein eigenes [[Enumerable]]Attribut als aufzählbar oder nicht aufzählbar identifiziert . Sie können dies als Teil des Deskriptors der Eigenschaft anzeigen :

var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');

console.log(descriptor.enumerable); // true
console.log(descriptor.value);      // 1

console.log(descriptor);
// { value: 1, writable: true, enumerable: true, configurable: true }

Eine for..inSchleife durchläuft dann die Eigenschaftsnamen des Objekts.

var foo = { bar: 1, baz: 2};

for (var prop in foo)
    console.log(prop); // outputs 'bar' and 'baz'

Wertet jedoch nur die Anweisung aus - console.log(prop);in diesem Fall - für die Eigenschaften, deren [[Enumerable]]Attribut lautet true.

Diese Bedingung ist gegeben, weil Objekte viel mehr Eigenschaften haben , insbesondere aufgrund der Vererbung :

console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]

Jede dieser Eigenschaften ist noch für das Objekt vorhanden :

console.log('constructor' in foo); // true
console.log('toString' in foo);    // true
// etc.

Sie werden jedoch von der for..inSchleife übersprungen , da sie nicht aufzählbar sind.

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');

console.log(descriptor.enumerable); // false
Jonathan Lonowski
quelle
Die Konstruktoreigenschaft ist also nicht aufzählbar, da sie nicht in der for..in-Schleife angezeigt wird. Während die Namen der Eigenschaften wie bar oder baz aufzählbar sind, weil Sie in der Lage waren, jeden einzelnen aus dem Objekt zu console.log?
Patrick
5
Dies ist nicht ganz richtig : But, they are skipped (or not counted) by the for..in loop because they are not enumerable. Die Eigenschaften von Object.prototypewerden tatsächlich ignoriert, weil sie sich weiter oben in der Prototypenkette befinden, nicht weil sie nicht aufzählbar sind. Weder noch getOwnPropertyNames()oder keys()Eigenschaften anzeigen, die nicht Eigentum eines Objekts sind. Nebenbei bemerkt, es stimmt, dass viele der integrierten Eigenschaften nicht aufzählbar sind und daher nicht mit angezeigt werden. keys()Sie müssen jedoch zusätzlichen Code schreiben, wenn Sie die Prototypenkette durchlaufen möchten.
Magnus
Christian Matthew
49

Wenn Sie ein Objekt über myObj = {foo: 'bar'}oder etwas in der Nähe erstellen , sind alle Eigenschaften aufzählbar. Die einfachere Frage ist also, was nicht aufzählbar ist. Bestimmte Objekte haben einige nicht aufzählbare Eigenschaften. Wenn Sie beispielsweise Object.getOwnPropertyNames([])[[ein Array aller aufzählbaren oder nicht aufzählbaren Eigenschaften auf [] zurückgeben) aufrufen , wird ['length']die nicht aufzählbare Eigenschaft eines Arrays, 'length', zurückgegeben. .

Sie können Ihre eigenen nicht aufzählbaren Eigenschaften erstellen, indem Sie aufrufen Object.defineProperty :

var person = { age: 18 };
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false });

person.name; // 'Joshua'
for (prop in person) {
  console.log(prop);
}; // 'age'

Dieses Beispiel leiht sich stark aus nicht aufzählbaren Eigenschaften in JavaScript , zeigt jedoch ein Objekt, über das aufgezählt wird. Eigenschaften können entweder beschreibbar, konfigurierbar oder aufzählbar sein oder nicht. John Resig diskutiert dies im Rahmen von ECMAScript 5-Objekten und -Eigenschaften .

Und es gibt eine Frage zum Stapelüberlauf, warum Sie Eigenschaften jemals nicht aufzählbar machen möchten .

Carpeliam
quelle
Hm, sowohl positive als auch negative Stimmen. Wenn es an dieser Antwort etwas gibt, das es wert ist, abgelehnt zu werden, fügen Sie bitte hier einen Kommentar hinzu.
Carpeliam
1
Eine andere Antwort schrieb dies: var o = {}; o ['foo'] = 0; // enumerable, normal Object.defineProperty (o, 'bar', {value: 1}); // nicht aufzählbar, seltsam Warum explizit enumerable hinzufügen: false?
Patrick
5
@Patrick, ich habe es hier teilweise eingefügt, damit aus dem Beispiel hervorgeht, dass es eine Option ist, aber abhängig von Ihrer Zielgruppe kann es eine solide Entscheidung sein, explizit zu sein, nur damit es jedem klar ist, der Ihren Code liest.
Carpeliam
@carpeliam Danke für diese kurze und sehr klare Erklärung, ich konnte keine akzeptierte Antwort erhalten, bis ich Ihre durchgesehen habe: D
sandeepKumar
36

Es ist viel langweiliger als etwas, das visualisiert werden sollte.

Es gibt buchstäblich ein Attribut für alle Eigenschaften, das als "aufzählbar" bezeichnet wird. Wenn der Wert auf false gesetzt ist, for..inüberspringt die Methode diese Eigenschaft und gibt vor, dass sie nicht vorhanden ist.

Es gibt viele Eigenschaften für Objekte, für die "enumerable" auf "false" gesetzt ist, wie "valueOf" und "hasOwnProperty", da davon ausgegangen wird, dass die JavaScript-Engine diese nicht durchlaufen soll.

Mit der folgenden Object.definePropertyMethode können Sie Ihre eigenen nicht aufzählbaren Eigenschaften erstellen :

  var car = {
    make: 'Honda',
    model: 'Civic',
    year: '2008',
    condition: 'bad',
    mileage: 36000
  };

  Object.defineProperty(car, 'mySecretAboutTheCar', {
    value: 'cat pee in back seat',
    enumerable: false
  });

Jetzt ist die Tatsache, dass es sogar ein Geheimnis über das Auto gibt, verborgen. Natürlich können sie immer noch direkt auf die Immobilie zugreifen und die Antwort erhalten:

console.log(car.mySecretAboutTheCar); // prints 'cat pee in back seat'

Aber würden sie müssen wissen , dass die Eigenschaft vorhanden ersten, denn wenn sie versuchen , darauf zuzugreifen durch for..inoder Object.keyses bleibt völlig geheim:

console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']

Sie hätten es einfach "forInAble" nennen sollen.

Gabriel Kunkel
quelle
5
Upvoted für diese letzte Zeile - ich denke, wenn sie tatsächlich für InAble aufgerufen worden wäre, würde niemand danach fragen. Was meine Frage aufwirft: Warum würden Sie (oder warum müssten Sie) eine Eigenschaft so einstellen, dass sie nicht aufzählbar ist? Die length-Eigenschaft eines Arrays wird häufig als Beispiel für eine nicht aufzählbare Eigenschaft verwendet, aber warum konnten Sie sie nicht einfach auf enumerable setzen (nicht die JavaScript-Einschränkung, ich meine, warum wurde sie in JavaScript in nicht aufzählbar gesetzt? den ersten Platz)?
Chris
Um meine Frage zu klären, warum wurde entschieden, dass Folgendes nicht in Frage kam: Marke: Honda-Modell: Bürgergeheimnis: Katzenpinklänge : 12
Chris
Hmmm ... Ich habe vielleicht die Antwort auf meine eigene Frage gefunden. Aus einer Google-Suche nach "Was meinen Sie mit aufgezählten Datentypen?" Aufzählungsdaten haben einen endlichen Satz von Werten. Ein Aufzählungsdatentyp besteht aus Werten, die Sie für diesen Typ zulassen, oder Aufzählungswerten. Bei ganzzahligen Aufzählungstypen besteht jeder Aufzählungswert aus einem Namen und einem zugrunde liegenden numerischen Wert. Wenn ich das richtig verstehe, müssten Sie eine unendliche Anzahl von Namen und einen Namen zuweisen, da es unendlich viele mögliche Längen gibt zu jeder Länge. Ist das korrekt?
Chris
Wenn Sie Ihre erste Frage beantworten und eine nicht aufzählbare Eigenschaft für ein Objekt festlegen, ist dies ein wenig schwierig, da Sie nur herausfinden können, was sich auf diesem Objekt befindet, indem Sie sich den Code und eine Codebasis ansehen entwickelt es könnte begraben werden. Im Allgemeinen möchten Sie es also nicht verwenden. In Bezug auf '.length', das die Anzahl der Zeichen in einer Zeichenfolge oder von Elementen in einem Array angibt, wird nur angenommen, dass wir nicht möchten, wenn wir 'for ... in' verwenden. Ich kann nicht antworten, warum die Götter von Js es unbedingt so gemacht haben. Sie haben Gründe ( ähm ) Meinungen, die wir nicht verstehen.
Gabriel Kunkel
... und ich glaube nicht, dass ich Ihre zweite Frage zu aufgezählten Datentypen beantworten könnte, obwohl es so aussieht, als könnte ich eine ganze Weile daran kauen, wenn ich Zeit hätte. :-)
Gabriel Kunkel
9

Wenn Sie Schwierigkeiten haben, sich vorzustellen, "was bedeutet es, aufzählbar zu sein?" warum fragst du dich nicht, was es heißt, nicht zahlreich zu sein ?

Ich denke ein bisschen so, eine nicht aufzählbare Eigenschaft existiert , ist aber teilweise verborgen ; was bedeutet, dass nicht unzählbar die seltsame ist. Jetzt können Sie sich vorstellen, was noch übrig ist - die natürlichere Eigenschaft, auf die wir seit der Entdeckung von Objekten stoßen . Erwägen

var o = {};
o['foo'] =  0;                               // enumerable, normal
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird

for..inStellen Sie sich das in einem Pseudocode vor

for property in o:
    if not property enumerable continue // skip non-enumerable, "bar"
    else do /* whatever */              // act upon enumerable, "foo"

wo der Körper der Schleife von Ihnen eingegebenen JavaScript ist an der Stelle der/* whatever */

Paul S.
quelle
8

Ich werde eine einzeilige Definition von ENUMERABLE schreiben

Enumerable: Gibt an, ob die Eigenschaft in einer for / in-Schleife zurückgegeben werden kann.

var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]
Ved
quelle
0

Methoden sind nicht aufzählbar; oder vielmehr eingebaute Methoden sind nicht .. tho nach der Suche nach dem, was Enumerable für Java-Skript bedeutet; es bezieht sich nur auf ein Eigenschaftsattribut .. alle in ecma3 erstellten Objekte sind aufzählbar, und ecma5 können Sie jetzt definieren .... das war's ..: D lol hat mich ein bisschen gebraucht, um die Antwort zu finden; Aber ich glaube, es wird in David Flanagans Buch darüber gesprochen. Ich denke, es bedeutet "versteckt" oder nicht "versteckt", da Methoden nicht in der for-in-Schleife gezeigt werden und daher "versteckt" sind.

user316264
quelle
0

Stellen Sie sich den Datentyp enum vor, nur eine Struktur von Objekten, die unterschiedlichen Zahlen entsprechen. Etwas als Aufzählungszeichen zu deklarieren bedeutet, zu deklarieren, dass es einer bestimmten Zahl entspricht, sodass es einen Platz in einem Wörterbuch erhalten kann, das zählbare Komponenten eines Objekts darstellt. Um es einfach auszudrücken: Ein Objekt aufzählbar zu machen, ist dasselbe wie dem Compiler zu sagen: "Hey, diese Eigenschaft zählt, ich möchte dies sehen, wenn ich nach Daten für dieses Objekt suche."

Jeshawn Chrite
quelle
0

Integrierte Methoden, die Objekte erben, sind nicht aufzählbar, aber die Eigenschaften, die Ihr Code Objekten hinzufügt, sind aufzählbar, sofern nicht ausdrücklich angegeben

parveen mittal
quelle