Jumlah elemen dalam objek javascript

104

Apakah ada cara untuk mendapatkan (dari suatu tempat) jumlah elemen dalam objek javascript ?? (yaitu kompleksitas waktu konstan).

Saya tidak dapat menemukan properti atau metode yang mengambil informasi itu. Sejauh ini saya hanya bisa memikirkan melakukan iterasi melalui seluruh koleksi, tapi itu waktu linier.
Aneh tidak ada akses langsung ke ukuran objek, bukan begitu.

EDIT:
Saya sedang berbicara tentang Objectobjek (bukan objek secara umum):

var obj = new Object ;
Mendapatkan gratis
sumber
5
Sudah dijawab di sini stackoverflow.com/questions/126100/… Object.keys (obj) .length
spats

Jawaban:

155

Meskipun implementasi JS mungkin melacak nilai seperti itu secara internal, tidak ada cara standar untuk mendapatkannya.

Di masa lalu, varian Javascript Mozilla mengekspos non-standar__count__ , tetapi telah dihapus dengan versi 1.8.5.

Untuk skrip lintas browser Anda terjebak dengan iterasi eksplisit atas properti dan memeriksa hasOwnProperty():

function countProperties(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            ++count;
    }

    return count;
}

Dalam kasus implementasi yang mampu ECMAScript 5, ini juga dapat ditulis sebagai (Kudos to Avi Flax )

function countProperties(obj) {
    return Object.keys(obj).length;
}

Ingatlah bahwa Anda juga akan kehilangan properti yang tidak dapat dihitung (misalnya, array length).

Jika Anda menggunakan kerangka kerja seperti jQuery, Prototype, Mootools, $ anything-the-latest-hype, periksa apakah mereka datang dengan API koleksi mereka sendiri, yang mungkin merupakan solusi yang lebih baik untuk masalah Anda daripada menggunakan objek JS asli.

Christoph
sumber
11
Sialan aku selalu lupa hasOwnProperty. Terlalu banyak waktu di tanah .NET, saya beritahu Anda. +1
annakata
2
jQuery menggunakan objek untuk koleksinya yang didapat dari kueri, dan itu mengekspos nilai itu dengan properti length.
Nosredna
6
Firefox4 __count__tidak ada :(
Timo Huovinen
1
Apakah ada cara untuk melakukan ini tanpa masuk? Saya berada dalam jenis pengikatan yang sama tetapi saya ingin membuatnya melewati JSLint jika memungkinkan.
lampu jalan
1
mengapa kita butuh hasOwnProperty()?
swisswiss
100

Untuk melakukan ini di lingkungan yang kompatibel dengan ES5

Object.keys(obj).length

(Dukungan browser dari sini )
(Doc on Object.keys di sini , termasuk metode yang dapat Anda tambahkan ke browser non-ECMA5)

ZelkiN
sumber
2
Ini bukan pertanyaan yang tepat untuk mengajukan jawaban ini. Dengan itu Anda mengambil semua kunci objek, meletakkannya dalam array yang baru dibuat dan kemudian mengambil properti length dari array baru tersebut.
Dapatkan Gratis
13
Ini mungkin bukan yang paling efisien secara programatik, tetapi paling efisien bagi pengembang.
superluminary
9

jika Anda sudah menggunakan jQuery di build Anda, lakukan ini:

$(yourObject).length

Ini berfungsi dengan baik untuk saya pada objek, dan saya sudah memiliki jQuery sebagai ketergantungan.

IndelibleHeff
sumber
5
Aneh ... ini tidak berhasil untukku. Saya selalu mendapatkan 1. Jawaban ZelkiN berhasil untuk saya.
mike rodent
3
Kode ini selalu mengembalikan 1. Hanya 1 objek. Itu tidak menghitung elemen di dalamnya
BeRocket
5
function count(){
    var c= 0;
    for(var p in this) if(this.hasOwnProperty(p))++c;
    return c;
}

var O={a: 1, b: 2, c: 3};

count.call(O);
kennebec
sumber
2

AFAIK, tidak ada cara untuk melakukan ini dengan andal, kecuali Anda beralih ke array. Sejujurnya, tidak tampak aneh - bagi saya tampaknya cukup lurus ke depan bahwa array dapat dihitung, dan objek tidak.

Mungkin yang paling dekat yang akan Anda dapatkan adalah seperti ini

// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this ) i++;
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3

Tapi ini menimbulkan masalah, atau setidaknya pertanyaan. Semua properti yang dibuat pengguna dihitung, termasuk fungsi _length itu sendiri! Dan sementara dalam contoh sederhana ini Anda dapat menghindarinya hanya dengan menggunakan fungsi normal, itu tidak berarti Anda dapat menghentikan skrip lain melakukan ini. jadi apa yang kamu lakukan? Abaikan properti fungsi?

Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this )
  {
      if ( 'function' == typeof this[p] ) continue;
      i++;
  }
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2

Pada akhirnya, saya pikir Anda mungkin harus membuang ide untuk membuat objek Anda dapat dihitung dan mencari cara lain untuk melakukan apa pun yang Anda lakukan.

Peter Bailey
sumber
8
BAHAYA AKAN ROBINSON! Apakah TIDAK proto terhadap Obyek! Semuanya turun dari Object, Anda akan melumpuhkan pemrosesan klien seperti ini jika Anda melakukan sejumlah besar pekerjaan JS.
annakata
5
Uh ... apakah Anda tidak membaca bagian di mana saya menulis di komentar "Menambal monyet dengan tujuan untuk membuat suatu maksud" - ayolah, saya melakukannya dengan sengaja agar orang tidak membalikkan sedikit tentang itu. Selain itu, meskipun saya tidak menganjurkan penambalan monyet, Anda salah paham tentang cara kerja rantai prototipe di Javascript jika menurut Anda ini akan menyebabkan masalah kinerja video.yahoo.com/watch/111585/1027823
Peter Bailey
Jadi .. ini lakukan atau tidak?
OscarRyz
Dalam "Javascript: The Good Parts", dia membuat prototipe objek dengan metode "create ()". Saya percaya itu adalah buku definatif tentang Javascript.
Chris Dutrow
1

Konsep bilangan / panjang / dimensi tidak benar-benar masuk akal untuk sebuah Objek, dan membutuhkannya menunjukkan Anda benar-benar menginginkan Array untuk saya.

Edit: Tunjukkan kepada saya bahwa Anda menginginkan O (1) untuk ini. Sepengetahuan saya, tidak ada cara seperti itu, saya khawatir.

annakata
sumber
Dia mengusulkan iterasi sendiri, yang merupakan solusi ini. Dia membutuhkan cara O (1) untuk mencapai ini ...
Thomas Hansen
Anda benar. Benar-benar harus membaca pertanyaan dengan lebih teliti.
annakata
Sebenarnya, Objek adalah hal yang paling dekat dengan Peta yang ada di JS. Peta memang memiliki panjang.
Cristian Vrabie