ฉันจะเข้าถึงคุณสมบัติของวัตถุจาวาสคริปต์ได้อย่างไรหากฉันไม่รู้ชื่อ


124

สมมติว่าคุณมีวัตถุจาวาสคริปต์ดังนี้:

var data = { foo: 'bar', baz: 'quux' };

คุณสามารถเข้าถึงคุณสมบัติโดยใช้ชื่อคุณสมบัติ:

var foo = data.foo;
var baz = data["baz"];

แต่เป็นไปได้หรือไม่ที่จะได้รับค่าเหล่านี้หากคุณไม่ทราบชื่อคุณสมบัติ? ลักษณะที่ไม่เรียงลำดับของคุณสมบัติเหล่านี้ทำให้ไม่สามารถแยกออกจากกันได้หรือไม่?

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

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

คำตอบ:


144

คุณสามารถวนซ้ำปุ่มต่างๆดังนี้:

for (var key in data) {
  console.log(key);
}

บันทึก "ชื่อ" และ "ค่า"

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

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    console.log(key);
  }
}

ตามที่คุณระบุไว้ไม่รับประกันว่าคีย์จะอยู่ในลำดับใด ๆ สังเกตว่าสิ่งนี้แตกต่างจากสิ่งต่อไปนี้อย่างไร:

for each (var value in data) {
  console.log(value);
}

ตัวอย่างนี้ loops ผ่านค่าจึงจะเข้าสู่ระบบและProperty Name 0หมายเหตุ: for eachไวยากรณ์ส่วนใหญ่รองรับเฉพาะใน Firefox แต่ไม่รองรับในเบราว์เซอร์อื่น

หากเบราว์เซอร์เป้าหมายของคุณรองรับ ES5 หรือไซต์ของคุณมีes5-shim.js(แนะนำ) คุณยังสามารถใช้Object.keys:

var data = { Name: 'Property Name', Value: '0' };
console.log(Object.keys(data)); // => ["Name", "Value"]

และวนซ้ำกับArray.prototype.forEach:

Object.keys(data).forEach(function (key) {
  console.log(data[key]);
});
// => Logs "Property Name", 0

คุณเพิ่งทำสิ่งนั้นเป็นครั้งสุดท้ายและหนีไปได้จริงหรือ? ทำได้ดีมาก ... =)
nickl-

สิ่งนี้มีอยู่ใน Firefox ( เอกสาร ) แต่จุดที่ยุติธรรมที่ไม่เป็นสากล ฉันจะอัปเดตคำตอบเพื่อพูดถึงเรื่องนี้
Ron DeVera

28
การแจ้งเตือน btw เป็นวิธีที่ไม่ดีในการดีบักสิ่งต่างๆลอง console.log
StackOverflowed

นี่เป็นคำตอบที่ดีที่สุดเมื่อถามคำถาม แต่ฉันกำลังลบเครื่องหมายถูกออกเพราะ JS เวอร์ชันที่ใหม่กว่ามีเครื่องมือที่ดีกว่า
Adam Lassek

65

JavaScript เวอร์ชันเก่า (<ES5) ต้องการการใช้for..inลูป:

for (var key in data) {
  if (data.hasOwnProperty(key)) {
    // do something with key
  }
}

ES5 แนะนำObject.keysและArray # forEachซึ่งทำให้ง่ายขึ้นเล็กน้อย:

var data = { foo: 'bar', baz: 'quux' };

Object.keys(data); // ['foo', 'baz']
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux']
Object.keys(data).forEach(function (key) {
  // do something with data[key]
});

ES2017แนะนำObject.valuesและObject.entries.

Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]

1
ตอนนี้ตอบคำถามได้ดีมาก @Adam Lassek ทำได้ดีมาก
nickl-

การใช้ทั้ง 'name' และ 'value' เป็นคีย์ออบเจ็กต์ทำให้เข้าใจผิด ฟังก์ชันนี้จะส่งคืนเฉพาะคีย์ในรายการไม่ใช่ค่า {name1: 'value1', name2: 'value2'} จะหลีกเลี่ยงความสับสนสำหรับผู้เริ่มต้น Object.keys (ข้อมูล); // ['name1', 'name2']
James Nicholson

2
@JamesNicholson ฉันเห็นด้วยแก้ไขเพื่อให้สับสนน้อยลง
Adam Lassek


4

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

 Obj.prototype.toString= function(){
        var A= [];
        for(var p in this){
            if(this.hasOwnProperty(p)){
                A[A.length]= p+'='+this[p];
            }
        }

    return A.join(', ');
}

3
function getDetailedObject(inputObject) {
    var detailedObject = {}, properties;

    do {
        properties = Object.getOwnPropertyNames( inputObject );
        for (var o in properties) {
            detailedObject[properties[o]] = inputObject[properties[o]];
        }
    } while ( inputObject = Object.getPrototypeOf( inputObject ) );

    return detailedObject;
}

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

var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
    console.log('key: ' + o + '   value: ' + detailedObject[o]);
}

1
var obj = {
 a: [1, 3, 4],
 b: 2,
 c: ['hi', 'there']
 }
for(let r in obj){  //for in loop iterates all properties in an object
 console.log(r) ;  //print all properties in sequence
 console.log(obj[r]);//print all properties values
}

โดยที่คำตอบนี้ให้สิ่งที่ OP ต้องการ แต่มีคำอธิบายเล็กน้อยเกี่ยวกับสิ่งที่คุณกำลังทำและทำไม OP จึงควรใช้มันจะดีและอย่าลืม.hasOwnProperty()เมื่อใช้เพื่อทำซ้ำวัตถุ
Muhammad Omer Aslam

ขอบคุณฉันยอมรับว่า. hasOwnProperty () ทำซ้ำวัตถุ แต่มันวนซ้ำเพื่อตรวจสอบเงื่อนไขอย่างไรก็ตามการใช้มันเราไม่สามารถพิมพ์คุณสมบัติทั้งหมดของวัตถุได้ แก้ไขฉันถ้าฉันผิด
Mayank_VK

hasOwnProperty()วิธีการส่งกลับbooleanระบุว่าวัตถุที่มีคุณสมบัติที่ระบุไว้เป็นทรัพย์สินของตัวเอง (เมื่อเทียบกับการสืบทอดมัน) ดูตัวอย่าง
Muhammad Omer Aslam

1

คุณสามารถใช้Object.keys () "ซึ่งส่งคืนอาร์เรย์ของชื่อคุณสมบัติที่แจกแจงได้ของออบเจ็กต์ที่ระบุในลำดับเดียวกับที่เราได้รับจากการวนซ้ำปกติ"

คุณสามารถใช้วัตถุใด ๆ แทนstats:

var stats = {
  a: 3,
  b: 6,
  d: 7,
  erijgolekngo: 35
}
/*  this is the answer here  */
for (var key in Object.keys(stats)) {
  var t = Object.keys(stats)[key];
  console.log(t + " value =: " + stats[t]);
}


ช่วยเพิ่มคำอธิบายได้ไหม
Keith Pinson

Object.keys( stats )[key]ไม่มีเหตุผลจะเป็นundefinedเช่นนั้นเสมอไป
Adam Lassek

-2
var attr, object_information='';

for(attr in object){

      //Get names and values of propertys with style (name : value)
      object_information += attr + ' : ' + object[attr] + '\n'; 

   }


alert(object_information); //Show all Object

สิ่งนี้ไม่เพิ่มอะไรให้กับคำตอบที่ยอมรับและนำเสนอข้อมูลด้วยวิธีที่มีประโยชน์น้อยที่สุดเท่าที่จะเป็นไปได้ และไม่ได้คำนึงถึงคุณสมบัติที่สืบทอดมา
Adam Lassek
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.