Apa artinya enumerable?

151

Saya diarahkan ke halaman MDN for..in ketika ia mengatakan, "for..in Iterates atas properti enumerable dari suatu objek."

Lalu aku pergi ke Enumerability dan kepemilikan properti di mana ia mengatakan "Properti enumerable adalah mereka yang dapat diulang dengan for for..in loop."

Kamus ini mendefinisikan enumerable sebagai dapat dihitung, tetapi saya tidak dapat benar-benar memvisualisasikan apa artinya. Bisakah saya mendapatkan contoh sesuatu yang dapat dihitung?

Patrick
sumber
Apakah kamu mengerti apa for-in?
Dari jawaban yang saya dapat untuk..in memungkinkan semua properti enumerable dari suatu objek tersedia untuk digunakan dengan pernyataan for
Patrick
6
Makna paling sederhana adalah: apakah sebuah properti akan diproduksi oleh satu for inlingkaran atau tidak (bagi mereka yang tidak ingin mengetahui detailnya atau tidak peduli;))
Tomasz Racia

Jawaban:

158

Properti enumerable adalah properti yang dapat dimasukkan dan dikunjungi selama for..inloop (atau iterasi properti yang serupa, misalnya Object.keys()).

Jika properti tidak diidentifikasi sebagai enumerable, loop akan mengabaikan bahwa itu ada di dalam objek.

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"

Properti diidentifikasi sebagai enumerable atau bukan oleh [[Enumerable]]atributnya sendiri . Anda dapat melihat ini sebagai bagian dari deskriptor properti :

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 }

Sebuah for..inloop kemudian beralih melalui nama properti objek.

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

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

Tetapi, hanya mengevaluasi pernyataannya - console.log(prop);dalam hal ini - untuk properti yang [[Enumerable]]atributnya adalahtrue .

Kondisi ini terjadi karena objek memiliki lebih banyak properti , terutama dari warisan :

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

Masing-masing dari properti ini masih ada di objek :

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

Tapi, mereka dilewati oleh for..inloop karena mereka tidak terhitung.

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

console.log(descriptor.enumerable); // false
Jonathan Lonowski
sumber
Jadi properti konstruktor adalah non-enumerable karena tidak muncul di for..in loop. Sementara nama-nama properti seperti bar atau baz dapat dihitung karena Anda dapat console.log masing-masing dari objek?
Patrick
5
Hal ini tidak sepenuhnya benar: But, they are skipped (or not counted) by the for..in loop because they are not enumerable. Properti pada Object.prototypekenyataannya diabaikan karena mereka lebih lanjut rantai prototipe, bukan karena mereka tidak dapat dihitung. Baik getOwnPropertyNames()atau keys()menunjukkan properti yang bukan milik objek. Sebagai catatan tambahan, memang benar bahwa banyak properti bawaan tidak dapat dihitung dan dengan demikian tidak akan ditampilkankeys() , tetapi Anda harus menulis kode tambahan jika Anda ingin melintasi rantai prototipe.
Magnus
secara harafiah, enumerable berarti dapat dihitung
Christian Matthew
49

Jika Anda membuat objek melalui myObj = {foo: 'bar'}atau sesuatu tentang itu, semua properti dapat dihitung. Jadi pertanyaan yang lebih mudah diajukan adalah, apa yang tidak bisa dihitung? Objek tertentu memiliki beberapa properti non-enumerable, misalnya jika Anda memanggil Object.getOwnPropertyNames([])(yang mengembalikan array semua properti, enumerable atau tidak, pada []), ia akan kembali['length'] , yang mencakup properti non-enumerable dari array, 'length' .

Anda dapat membuat properti non-enumerable Anda sendiri dengan menelepon 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'

Contoh ini meminjam banyak dari properti yang tidak dapat dihitung dalam JavaScript , tetapi menunjukkan objek yang disebutkan. Properti bisa atau tidak bisa ditulis, dapat dikonfigurasi, atau dapat dihitung. John Resig membahas ini dalam ruang lingkup ECMAScript 5 Objects and Properties .

Dan, ada pertanyaan Stack Overflow tentang mengapa Anda ingin membuat properti tidak dapat dihitung .

carpeliam
sumber
Hm, baik upvotes dan downvotes. Tentu saja, jika ada sesuatu tentang jawaban ini yang layak untuk dibatalkan, silakan tambahkan komentar di sini.
carpeliam
1
Jawaban lain menulis ini: var o = {}; o ['foo'] = 0; // enumerable, Object.defineProperty normal (o, 'bar', {value: 1}); // tidak dapat dihitung, aneh Mengapa secara eksplisit menambahkan enumerable: false?
Patrick
5
@ Patrick, saya memasukkannya di sini sebagian sehingga jelas dari contoh bahwa ini merupakan opsi, tetapi tergantung pada audiens Anda, menjadi eksplisit dapat menjadi keputusan yang solid hanya agar jelas bagi siapa saja yang membaca kode Anda.
carpeliam
@carpeliam Terima kasih atas penjelasan singkat dan sangat jelas ini, saya tidak dapat menerima jawaban sampai saya memeriksa jawaban Anda: D
sandeepKumar
37

Ini jauh lebih membosankan daripada sesuatu yang harus divisualisasikan.

Secara harfiah ada atribut pada semua properti yang disebut "enumerable." Ketika disetel ke false, for..inmetode akan melewati properti itu, berpura-pura itu tidak ada.

Ada banyak properti pada objek yang memiliki "enumerable" disetel ke false, seperti "valueOf" dan "hasOwnProperty," karena dianggap Anda tidak ingin mesin JavaScript mengulanginya.

Anda dapat membuat properti non-enumerable Anda sendiri menggunakan Object.definePropertymetode:

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

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

Sekarang, fakta bahwa bahkan ada rahasia tentang mobil itu tersembunyi. Tentu saja mereka masih dapat mengakses properti secara langsung dan mendapatkan jawabannya:

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

Tetapi, mereka harus tahu bahwa properti itu ada terlebih dahulu, karena jika mereka mencoba mengaksesnya for..inatau Object.keysitu akan tetap sepenuhnya rahasia:

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

Mereka seharusnya menyebutnya, "untuk InAble."

Gabriel Kunkel
sumber
5
Terpilih untuk baris terakhir - saya pikir jika itu benar-benar telah dipanggil untuk InAble tidak akan ada yang bertanya tentang itu sama sekali. Yang membawa pertanyaan saya - mengapa akan Anda (atau mengapa Anda harus) mengatur properti untuk tidak enumerable? Properti panjang array digunakan cukup sering sebagai contoh properti non-enumerable, tetapi mengapa Anda tidak bisa mengaturnya menjadi enumerable (bukan pembatasan JavaScript, maksud saya, mengapa itu diatur untuk tidak dapat dihitung dalam JavaScript di posisi pertama)?
Chris
Untuk memperjelas pertanyaan saya, mengapa diputuskan bahwa yang berikut ini bukan pilihan: buat: model Honda: Civic secret: Cat pee length: 12
Chris
Hmmm ... Saya mungkin telah menemukan jawaban untuk pertanyaan saya sendiri. Dari pencarian google untuk "Apa yang Anda maksud dengan tipe data yang disebutkan?" Data yang dihitung memiliki seperangkat nilai yang terbatas. Tipe data yang disebutkan terdiri dari nilai yang Anda izinkan untuk jenis itu, atau nilai yang disebutkan. Untuk tipe enumerasi berbasis integer, setiap nilai enumerasi terdiri dari nama dan nilai numerik yang mendasarinya. Jadi, jika saya mengerti dengan benar, karena ada jumlah panjang tak terhingga yang mungkin, Anda harus menetapkan jumlah nama tak terbatas, satu nama untuk setiap panjangnya. Apakah itu benar?
Chris
Nah, menjawab pertanyaan pertama Anda, menetapkan properti yang tidak dapat dihitung pada suatu objek sedikit membingungkan, karena satu-satunya cara Anda dapat mengetahui apa yang ada pada objek itu adalah dengan melihat kode dan sebagai basis kode berkembang itu bisa dikubur. Jadi, secara umum, Anda tidak ingin menggunakannya. Mengenai '.length' yang memberikan jumlah karakter dalam string atau elemen dalam array adalah sesuatu yang dianggap tidak ingin dimasukkan jika kita menggunakan 'for ... in.' Tidak bisa menjawab mengapa para dewa Js berhasil seperti itu. Mereka memiliki alasan ( ahem ) pendapat di luar pemahaman kita.
Gabriel Kunkel
... dan saya rasa saya tidak bisa menjawab pertanyaan kedua Anda tentang tipe data yang disebutkan, meskipun sepertinya sesuatu yang bisa saya coba untuk sementara waktu jika saya punya waktu. :-)
Gabriel Kunkel
9

Jika Anda mengalami kesulitan memvisualisasikan "apa artinya menjadi enumerable?" mengapa tidak bertanya pada diri sendiri, apa artinya menjadi tak terhitung ?

Saya memikirkannya sedikit seperti ini, properti yang tidak dapat dihitung ada tetapi sebagian tersembunyi ; artinya tidak dapat dihitung adalah yang aneh. Sekarang Anda dapat membayangkan enumerable sebagai apa yang tersisa - properti yang lebih alami yang kami temui sejak kami menemukan Objects . Mempertimbangkan

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

Sekarang for..in, bayangkan itu seperti kodesemu

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

di mana tubuh loop yang Anda ketikkan dalam JavaScript berada di tempat/* whatever */

Paul S.
sumber
8

Saya akan menulis satu definisi garis ENUMERABLE

Enumerable: Menentukan apakah properti dapat dikembalikan dalam for / in loop.

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

metode tidak dapat dihitung; atau lebih tepatnya metode yang dibangun bukan .. tho setelah mencari apa artinya enumerable untuk skrip java; itu hanya merujuk ke atribut properti .. semua objek yang dibuat di ecma3 dapat dihitung, dan sekarang ecma5 Anda dapat mendefinisikannya .... itu saja ..: D lol butuh sedikit untuk menemukan jawabannya; tapi saya percaya itu dibicarakan dalam buku David Flanagan .. jadi saya kira itu berarti "tersembunyi", atau tidak "tersembunyi" dalam metode yang tidak ditampilkan dalam for in loop, dan dengan demikian "tersembunyi"

pengguna316264
sumber
0

Pikirkan tipe data enum, hanya struktur objek yang sesuai dengan angka yang berbeda. Untuk mendeklarasikan sesuatu sebagai enumerable berarti menyatakan bahwa itu sesuai dengan angka tertentu, yang memungkinkannya diberikan tempat dalam Kamus yang mewakili komponen yang dapat dihitung dari suatu objek. Sederhananya, membuat objek yang dapat dihitung sama dengan mengatakan pada kompiler, "Hei, properti ini penting, saya ingin melihat ini ketika saya memeriksa data pada objek ini."

Jeshawn Chrite
sumber
0

Metode bawaan yang diwarisi objek tidak dapat dihitung, tetapi properti yang ditambahkan kode Anda ke objek dapat dihitung kecuali dinyatakan secara eksplisit

parveen mittal
sumber