จำนวนองค์ประกอบในวัตถุจาวาสคริปต์


105

มีวิธีรับ (จากที่ใดที่หนึ่ง) จำนวนองค์ประกอบในวัตถุ javascript หรือไม่? (เช่นความซับซ้อนของเวลาคงที่)

ฉันไม่พบคุณสมบัติหรือวิธีการที่ดึงข้อมูลนั้นมา จนถึงตอนนี้ฉันคิดได้แค่ว่าจะทำการวนซ้ำในคอลเลคชันทั้งหมด แต่นั่นคือเวลาเชิงเส้น
เป็นเรื่องแปลกที่ไม่มีการเข้าถึงขนาดของวัตถุโดยตรงอย่างที่คุณคิด

แก้ไข:
ฉันกำลังพูดถึงObjectวัตถุ (ไม่ใช่วัตถุทั่วไป):

var obj = new Object ;

5
ตอบอยู่ที่นี่แล้วstackoverflow.com/questions/126100/... Object.keys (obj) .length
ทะเลาะวิวาท

คำตอบ:


156

แม้ว่าการใช้งาน JS อาจติดตามค่าดังกล่าวภายใน แต่ก็ไม่มีวิธีมาตรฐานที่จะได้รับ

ในอดีตตัวแปร Javascript ของ Mozilla เปิดเผยถึงสิ่งที่ไม่ได้มาตรฐาน__count__แต่ถูกลบออกด้วยเวอร์ชัน 1.8.5

สำหรับการเขียนสคริปต์ข้ามเบราว์เซอร์คุณติดอยู่กับการทำซ้ำคุณสมบัติและการตรวจสอบอย่างชัดเจนhasOwnProperty():

function countProperties(obj) {
    var count = 0;

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

    return count;
}

ในกรณีของการใช้งานที่มีความสามารถ ECMAScript 5 สิ่งนี้สามารถเขียนเป็น (Kudos to Avi Flax )

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

โปรดทราบว่าคุณจะพลาดคุณสมบัติที่ไม่สามารถนับได้ (เช่นอาร์เรย์length)

หากคุณใช้เฟรมเวิร์กเช่น jQuery, Prototype, Mootools, $ ใดก็ตามที่ใหม่ล่าสุดให้ตรวจสอบว่าพวกเขามาพร้อมกับคอลเลกชัน API ของตัวเองหรือไม่ซึ่งอาจเป็นวิธีแก้ปัญหาที่ดีกว่าการใช้ออบเจ็กต์ JS ดั้งเดิม


11
น่าเสียดายที่ฉันลืมเสมอว่า hasOwnProperty ฉันบอกเวลาในดินแดน. NET มากเกินไป +1
annakata

2
jQuery ใช้ออบเจ็กต์สำหรับคอลเลกชันที่ได้รับจากคิวรีและแสดงค่านั้นด้วยคุณสมบัติความยาว
Nosredna

6
Firefox4 __count__หายไป :(
Timo Huovinen

1
มีวิธีดำเนินการโดยไม่ใช้สำหรับในหรือไม่? ฉันเป็นคนประเภทเดียวกัน แต่ฉันต้องการให้มันผ่าน JSLint ถ้าเป็นไปได้
ไฟถนน

1
ทำไมเราถึงต้องการhasOwnProperty()?
swisswiss

100

เพื่อทำสิ่งนี้ในสภาพแวดล้อมที่เข้ากันได้กับ ES5

Object.keys(obj).length

(การสนับสนุนเบราว์เซอร์จากที่นี่ )
(เอกสารใน Object.keys ที่นี่รวมถึงวิธีการที่คุณสามารถเพิ่มลงในเบราว์เซอร์ที่ไม่ใช่ ECMA5)


2
นี่ไม่ใช่คำถามที่ถูกต้องในการตอบคำถามนี้ ด้วยการที่คุณใช้คีย์ทั้งหมดของวัตถุวางไว้ในอาร์เรย์ที่สร้างขึ้นใหม่แล้วดึงคุณสมบัติความยาวจากอาร์เรย์ใหม่นั้น
ฟรี

13
อาจไม่ใช่โปรแกรมที่มีประสิทธิภาพมากที่สุด แต่เป็นนักพัฒนาที่มีประสิทธิภาพสูงสุด
superluminary

9

หากคุณใช้ jQuery ในบิลด์ของคุณอยู่แล้วให้ทำสิ่งนี้:

$(yourObject).length

มันทำงานได้ดีสำหรับฉันกับวัตถุและฉันก็มี jQuery เป็นที่พึ่งแล้ว


5
แปลก ... นี่ใช้ไม่ได้กับฉัน ฉันมักจะได้รับ 1. คำตอบของ ZelkiN เหมาะกับฉัน
หนูไมค์

3
รหัสนี้ส่งคืน 1 เสมอเพียง 1 วัตถุ มันไม่นับองค์ประกอบในนั้น
BeRocket


2

AFAIK ไม่มีวิธีใดที่จะทำได้อย่างน่าเชื่อถือเว้นแต่คุณจะเปลี่ยนไปใช้อาร์เรย์ ซึ่งจริงๆแล้วมันก็ดูไม่แปลก - ดูเหมือนว่าจะตรงไปตรงมาสำหรับฉันที่อาร์เรย์สามารถนับได้และอ็อบเจ็กต์ไม่ได้

อาจเป็นสิ่งที่ใกล้เคียงที่สุดที่คุณจะได้รับคือสิ่งนี้

// 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

แต่สิ่งนี้สร้างปัญหาหรืออย่างน้อยก็เกิดคำถาม คุณสมบัติที่ผู้ใช้สร้างขึ้นทั้งหมดจะถูกนับรวมถึงฟังก์ชัน _length ด้วย! และในตัวอย่างง่ายๆนี้คุณสามารถหลีกเลี่ยงได้โดยใช้ฟังก์ชันปกติ แต่ไม่ได้หมายความว่าคุณสามารถหยุดสคริปต์อื่น ๆ ไม่ให้ทำสิ่งนี้ได้ แล้วคุณจะทำอย่างไร? ไม่สนใจคุณสมบัติของฟังก์ชัน?

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

ในท้ายที่สุดฉันคิดว่าคุณน่าจะทิ้งความคิดที่จะทำให้วัตถุของคุณสามารถนับได้และหาวิธีอื่นในการทำสิ่งที่คุณกำลังทำอยู่


8
โรบินสันจะเป็นอันตราย! ทำไม่โปรโตกับวัตถุ! ทุกอย่างมาจาก Object คุณจะทำให้ไคลเอนต์ประมวลผลแบบนี้ไม่ได้ถ้าคุณทำงาน JS จำนวนมาก ๆ
annakata

5
เอ่อ ... คุณไม่ได้อ่านส่วนที่ฉันเขียนไว้ในคอมเมนต์ "Monkey patching on purpose to make a point" หรือเปล่าฉันทำแบบนั้นโดยเจตนาเพื่อไม่ให้คนอื่นพลิกเรื่องนี้สักหน่อย นอกจากนี้แม้ว่าฉันจะไม่สนับสนุนการปะลิง แต่คุณเข้าใจผิดว่าห่วงโซ่ต้นแบบทำงานอย่างไรใน Javascript หากคุณคิดว่าสิ่งนี้จะทำให้เกิดปัญหาด้านประสิทธิภาพvideo.yahoo.com/watch/111585/1027823
Peter Bailey

นี่คือสิ่งที่ควรทำหรือไม่?
OscarRyz

ใน "Javascript: The Good Parts" เขาสร้างต้นแบบวัตถุด้วยเมธอด "create ()" ฉันเชื่อว่าเป็นหนังสือที่ชัดเจนใน Javascript
Chris Dutrow

1

แนวคิดเรื่องจำนวน / ความยาว / มิติไม่สมเหตุสมผลสำหรับ Object และการต้องการมันบ่งบอกว่าคุณต้องการ Array สำหรับฉันจริงๆ

แก้ไข: ชี้ให้ฉันเห็นว่าคุณต้องการ O (1) สำหรับสิ่งนี้ ฉันกลัวอย่างที่สุดเท่าที่จะรู้ได้


เขาเสนอตัวเองซ้ำซึ่งวิธีนี้คือ เขาต้องการวิธี O (1) เพื่อให้บรรลุสิ่งนี้ ...
Thomas Hansen

คุณค่อนข้างถูกต้อง จริงๆควรอ่านคำถามให้ละเอียดกว่านี้
annakata

จริงๆแล้ว Objects เป็นสิ่งที่ใกล้เคียงที่สุดกับ Map ที่มีใน JS แผนที่มีความยาว
Cristian Vrabie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.