Cosa significa enumerabile?


151

Sono stato indirizzato a MDN per..in pagina quando diceva "for..in Iterate sulle proprietà enumerabili di un oggetto".

Poi sono andato alla pagina Enumerabilità e proprietà delle proprietà dove diceva "Le proprietà enumerabili sono quelle che possono essere ripetute da un ciclo for..in".

Il dizionario definisce enumerabile come numerabile, ma non riesco davvero a visualizzare cosa significhi. Potrei avere un esempio di qualcosa che è enumerabile?


Capisci cosa for-infa?

Dalle risposte ho ottenuto che for..in consente a tutte le proprietà enumerabili di un oggetto di essere disponibili per l'uso con la dichiarazione for
Patrick

6
Il significato più semplice è: se una proprietà sarà prodotta da un for inciclo o no (per coloro che non vogliono conoscere i dettagli o semplicemente non si preoccupano;))
Tomasz Racia

Risposte:


158

Una proprietà enumerabile è una proprietà che può essere inclusa e visitata durante i for..incicli (o un'iterazione simile di proprietà, come Object.keys()).

Se una proprietà non è identificata come enumerabile, il ciclo ignorerà che si trova all'interno dell'oggetto.

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"

Una proprietà è identificata come enumerabile o meno dal proprio [[Enumerable]]attributo . Puoi vederlo come parte del descrittore della proprietà :

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 }

Un for..inciclo quindi scorre i nomi delle proprietà dell'oggetto.

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

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

Ma valuta solo la sua affermazione - console.log(prop);in questo caso - per quelle proprietà il cui [[Enumerable]]attributo è true.

Questa condizione è presente perché gli oggetti hanno molte più proprietà , in particolare per eredità :

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

Ognuna di queste proprietà esiste ancora sull'oggetto :

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

Ma vengono ignorati dal for..inloop perché non sono enumerabili.

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

console.log(descriptor.enumerable); // false

Quindi la proprietà del costruttore non è enumerabile perché non viene visualizzata nel ciclo for..in. Mentre i nomi delle proprietà come bar o baz sono enumerabili perché sei stato in grado di console.log ognuno dall'oggetto?
Patrick,

5
Questo non è del tutto corretto: But, they are skipped (or not counted) by the for..in loop because they are not enumerable. Le proprietà su Object.prototypesono infatti ignorate perché si trovano più in alto nella catena del prototipo, non perché non sono enumerabili. Né getOwnPropertyNames()o keys()mostrare le proprietà che non è un oggetto di sono proprio. Come nota a margine, è vero che molte delle proprietà integrate non sono enumerabili e quindi non verranno mostrate con keys(), ma dovrai scrivere un codice extra se vuoi attraversare la catena di prototipi.
Magnus,

letteralmente, enumerabile significa numerabile
Christian Matthew

49

Se si crea un oggetto tramite myObj = {foo: 'bar'}o qualcosa del genere, tutte le proprietà sono enumerabili. Quindi la domanda più semplice da porre è: cosa non è enumerabile? Alcuni oggetti hanno alcune proprietà non enumerabili, ad esempio se si chiama Object.getOwnPropertyNames([])(che restituisce un array di tutte le proprietà, enumerabili o no, su []), verrà restituito ['length'], che include la proprietà non enumerabile di un array, 'lunghezza' .

Puoi creare le tue proprietà non enumerabili chiamando 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'

Questo esempio prende in prestito pesantemente dalle proprietà non enumerabili in JavaScript , ma mostra un oggetto da enumerare. Le proprietà possono essere o meno scrivibili, configurabili o enumerabili. John Resig ne discute nell'ambito di ECMAScript 5 Oggetti e proprietà .

E c'è una domanda Stack Overflow sul motivo per cui vorresti mai rendere le proprietà non enumerabili .


Hm, sia voti positivi che negativi. Certamente, se c'è qualcosa su questa risposta che vale la pena di effettuare il downgrade, si prega di aggiungere un commento qui.
Carpeliam,

1
Un'altra risposta ha scritto questo: var o = {}; o ['foo'] = 0; // enumerabile, normale Object.defineProperty (o, 'bar', {valore: 1}); // non enumerabile, strano Perché aggiungere esplicitamente enumerable: false?
Patrick,

5
@Patrick, l'ho incluso qui in parte in modo che dall'esempio sia chiaro che è un'opzione, ma a seconda del tuo pubblico, essere espliciti può essere una decisione solida solo in modo che sia chiaro a chiunque stia leggendo il tuo codice.
carpeliam,

@carpeliam Grazie per questa breve e chiarissima spiegazione, non ho potuto ottenere la risposta accettata fino a quando non ho
esaminato la

37

È molto più noioso di qualcosa che dovrebbe essere visualizzato.

C'è letteralmente un attributo su tutte le proprietà chiamato "enumerable". Quando è impostato su false, il for..inmetodo salterà quella proprietà, fingendo che non esista.

Ci sono molte proprietà sugli oggetti che hanno "enumerabile" impostato su false, come "valueOf" e "hasOwnProperty", perché si presume che non si desideri che il motore JavaScript esegua iterazioni su tali.

Puoi creare le tue proprietà non enumerabili usando il Object.definePropertymetodo:

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

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

Ora, il fatto che ci sia persino un segreto sull'auto è nascosto. Naturalmente possono comunque accedere direttamente alla proprietà e ottenere la risposta:

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

Ma dovrebbero sapere che la proprietà esiste per prima, perché se stanno provando ad accedervi attraverso for..ino Object.keysrimarrà completamente segreta:

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

Avrebbero dovuto semplicemente chiamarlo "forInAble".


5
Eseguito l'upgrade per l'ultima riga - penso che se fosse stato effettivamente chiamato per InAble nessuno se lo sarebbe chiesto affatto. Il che porta in primo piano la mia domanda - perché sarebbe voi (o perché si deve), impostare una proprietà di non essere enumerabile? La proprietà length di un array viene usata abbastanza spesso come esempio di proprietà non enumerabile, ma perché non è possibile impostarla su enumerabile (non sulla restrizione JavaScript, voglio dire, perché è stata impostata su non enumerabile in JavaScript in il primo posto)?
Chris,

Per chiarire la mia domanda, perché è stato deciso che quanto segue non era un'opzione: marca: modello Honda: segreto civico: lunghezza
Chris

Hmmm ... Potrei aver trovato la risposta alla mia domanda. Da una ricerca su Google "Cosa intendi per tipi di dati enumerati?" I dati enumerati hanno un set finito di valori. Un tipo di dati enumerato è costituito da valori consentiti per quel tipo o da valori enumerati. Per i tipi enumerati basati su numeri interi, ciascun valore enumerato è costituito da un nome e da un valore numerico sottostante. Quindi, se ho capito bene, poiché esiste un numero infinito di possibili lunghezze, dovresti assegnare un numero infinito di nomi, un nome per ogni lunghezza. È corretto?
Chris,

Bene, rispondere alla tua prima domanda, impostare una proprietà non enumerabile su un oggetto è un po 'confuso, dal momento che l'unico modo in cui potresti scoprire cosa c'era su quell'oggetto sarebbe guardare il codice e come base di codice sviluppa potrebbe essere sepolto. Quindi, in generale, non vorrai usarlo. Per quanto riguarda ".length" che indica il numero di caratteri in una stringa o elementi in un array è solo qualcosa che si presume non vorremmo includere se usassimo "for ... in." Non posso rispondere perché gli dei di Js lo fecero necessariamente in quel modo. Hanno ragioni ( ehm ) opinioni oltre la nostra comprensione.
Gabriel Kunkel il

... e non credo di poter rispondere alla tua seconda domanda sui tipi di dati enumerati, anche se sembra qualcosa che potrei masticare per un bel po 'se avessi il tempo. :-)
Gabriel Kunkel il

9

Se hai difficoltà a visualizzare "cosa significa essere enumerabili?" perché non chiederti, cosa significa essere non numerabili ?

Ci penso un po 'così, esiste una proprietà non numerabile ma è parzialmente nascosta ; nel senso che non numerabile è quello strano. Ora puoi immaginare l'enumerabile come ciò che resta: la proprietà più naturale che siamo abituati a incontrare da quando abbiamo scoperto gli oggetti . Tener conto di

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

Ora in a for..in, immaginalo come uno pseudocodice

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

dove si trova il corpo del loop digitato in JavaScript al posto di/* whatever */


8

Scriverò una definizione di riga di ENUMERABLE

Enumerable: Specifica se la proprietà può essere restituita in un ciclo for / in.

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

0

i metodi non sono enumerabili; o meglio costruito in metodi non sono .. tho dopo la ricerca su ciò che enumerabili mezzi per java script; si riferisce solo ad un attributo di proprietà .. tutti gli oggetti creati in ecma3 sono enumerabili e ecma5 ora puoi definirlo .... tutto qui ..: D lol mi ha preso un po 'per trovare la risposta; ma credo che ne parli nel libro di David Flanagan .. quindi immagino che significhi "nascosto", o non "nascosto" in quanto i metodi non sono mostrati nel for in loop, e quindi sono "nascosti"


0

Pensa al tipo di dati enum, solo una struttura di oggetti che corrispondono a numeri diversi. Dichiarare qualcosa come un enumerabile significa dichiarare che corrisponde a un numero specifico, consentendogli di avere un posto in un dizionario che rappresenta componenti numerabili di un oggetto. Per dirla semplicemente, rendere un oggetto enumerabile equivale a dire al compilatore: "Ehi, questa proprietà conta, voglio vederlo quando cerco i dati su questo oggetto".


0

I metodi incorporati che gli oggetti ereditano non sono enumerabili, ma le proprietà che il codice aggiunge agli oggetti sono enumerabili se non indicato esplicitamente

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.