เข้าถึงคุณสมบัติของวัตถุที่ไม่ใช่ตัวเลขโดยดัชนี?


88

ถ้าฉันมีอาร์เรย์เช่นนี้:

var arr = ['one','two','three'];

ฉันสามารถเข้าถึงส่วนต่างๆได้โดยทำสิ่งนี้:

console.log(arr[1]);

ฉันจะเข้าถึงคุณสมบัติของอ็อบเจ็กต์ตามลำดับไม่ใช่ด้วยคีย์ได้อย่างไร

ตัวอย่าง:

var obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
},
jbo = {
    'evenmore'  : 'crazy',
    'something' : 'awesome'
};

ฉันจะได้รับคุณสมบัติแรกสำหรับแต่ละออบเจ็กต์ - "บางสิ่ง" จากobjและ "ยิ่งกว่านั้น" ได้อย่างไร - jboโดยไม่ใช้ชื่อคุณสมบัติอย่างชัดเจน

ตอนนี้ดูเหมือนคุณไม่กี่คนจะคิดว่าฉันชอบ:

console.log(obj['something']);

นี่ไม่ใช่กรณีฉันต้องการกำหนดเป้าหมายดัชนีโดยเฉพาะเช่นเดียวกับตัวอย่างแรก - ถ้าเป็นไปได้


2
คุณหมายถึงอะไร "Object array" อาร์เรย์คือวัตถุ คุณหมายถึงแค่วัตถุที่ไม่ใช่อาร์เรย์หรือคุณหมายถึงอาร์เรย์ของวัตถุ และ jQuery มีส่วนเกี่ยวข้องกับคำถามของคุณอย่างไร? ตัวอย่างโค้ดเดียวของคุณแสดงให้เห็นถึงส่วนที่คุณรู้แล้วว่าต้องทำอย่างไร วิธีการเกี่ยวกับการให้รหัสบางอย่างที่แสดงให้เห็นถึงปัญหาที่เกิดขึ้น
user113716

@ Ӫ _._ Ӫเหตุผลที่ฉันติดแท็ก jQuery คือการได้ผู้ชมที่กว้างขึ้นฉันคิดว่าใครก็ตามที่รู้จัก jQuery จะต้องมีความเข้าใจเกี่ยวกับอาร์เรย์ไม่ใช่เพื่อขัดแย้งกับคำถามของฉันมันเป็นตำราเรียน
daryl

4
ที่จริงฉันว่ามีคน "รู้" jQuery และไม่รู้จัก JavaScript มากกว่าในทางกลับกัน (อย่างน้อยคนที่รู้จัก JavaScript ก็น่าจะเข้าใจ jQuery ได้ง่าย) .... และสำหรับคำถามที่แท้จริงของคุณ: ไม่คุณ ไม่สามารถเข้าถึงคุณสมบัติ objec โดยดัชนี พวกเขาไม่ได้รับคำสั่ง
Felix Kling

2
"... ฉันคิดว่าใครก็ตามที่รู้จัก jQuery จะต้องมีความเข้าใจในอาร์เรย์ของ ... "ฉันจะไม่พนันเลย
user113716

1
@ โปรแกรมเมอร์: คำถามนี้ไม่มีส่วนเกี่ยวข้องกับ jQuery ดังนั้นแท็ก jQuery จึงไม่เหมาะสม
outis

คำตอบ:


127

"ฉันต้องการกำหนดเป้าหมายดัชนีโดยเฉพาะเช่นเดียวกับตัวอย่างแรก - ถ้าเป็นไปได้"

ไม่เป็นไปไม่ได้

สิ่งที่ใกล้เคียงที่สุดที่คุณจะได้รับคือการรับ Array ของคีย์ของวัตถุและใช้สิ่งนั้น:

var keys = Object.keys( obj );

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

keys[ 0 ];  // 'evenmore'
keys[ 1 ];  // 'something'

6
Object.keys()สามารถใช้ได้อย่างน่าเชื่อถือหากคุณทราบเนื้อหาของวัตถุ รายละเอียดเพิ่มเติมที่นี่: stackoverflow.com/questions/280713/…
cronoklee

3
เมธอด Object.keys () ส่งคืนอาร์เรย์ของคุณสมบัติที่นับได้ของอ็อบเจ็กต์ที่กำหนดเองตามลำดับเดียวกับที่จัดทำโดย for ... in loop (ความแตกต่างที่ for-in loop จะแจกแจงคุณสมบัติในห่วงโซ่ต้นแบบเป็น ดี). developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Amr Ragaey

6
ทุกอย่างเป็นไปได้
Cas Bloem

48

Object.keys();วิธีเดียวที่ฉันจะคิดว่าการทำเช่นนี้คือการสร้างวิธีการที่จะช่วยให้คุณทรัพย์สินที่ใช้

var obj = {
    dog: "woof",
    cat: "meow",
    key: function(n) {
        return this[Object.keys(this)[n]];
    }
};
obj.key(1); // "meow"

การสาธิต: http://jsfiddle.net/UmkVn/

เป็นไปได้ที่จะขยายสิ่งนี้ไปยังวัตถุทั้งหมดที่ใช้ Object.prototype;แต่มักไม่แนะนำ

ให้ใช้ตัวช่วยฟังก์ชันแทน:

var object = {
  key: function(n) {
    return this[ Object.keys(this)[n] ];
  }
};

function key(obj, idx) {
  return object.key.call(obj, idx);
}

key({ a: 6 }, 0); // 6

1
มันเจ๋งและใช้งานได้เหมือนมีเสน่ห์! เหตุใดจึงไม่เป็นคำตอบที่ยอมรับ คุณควรใช้return this[Object.keys(this)[n]];เพื่อทำให้เป็นแบบทั่วไป
cronoklee

3
สวัสดีจากปี 2559 พวกเราชาวบ้านในอนาคตยังคงคิดว่านี่น่าจะเป็นคำตอบที่ได้รับการยอมรับ วิธีแก้ปัญหาที่ดี
mhodges

สาเหตุที่ไม่ใช่คำตอบที่ยอมรับได้เนื่องจากจนถึง es6 จะไม่รับประกันลำดับของ Object.keys ดังนั้นแม้ว่าโค้ดดังกล่าวจะใช้งานได้กับเอ็นจิน JS ไม่กี่ตัว แต่ก็ไม่รับประกันว่าจะทำงานได้ทั้งหมด stackoverflow.com/questions/5525795/…
ptoinson

13

คุณสามารถใช้Object.values()วิธีนี้หากคุณไม่ต้องการใช้ไฟล์Object.keys().

ซึ่งตรงข้ามกับObject.keys()วิธีการที่ส่งคืนอาร์เรย์ของคุณสมบัติที่นับได้ของออบเจ็กต์ที่กำหนดเองตัวอย่างเช่น:

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.keys(object1));

จะพิมพ์อาร์เรย์ต่อไปนี้:

[ 'a', 'b', 'c' ]

วิธีการส่งกลับอาร์เรย์ของสถานที่ให้บริการนับเป็นวัตถุที่กำหนดเองObject.values()values

ดังนั้นหากคุณมีวัตถุเดียวกัน แต่ใช้ค่าแทน

const object1 = {
 a: 'somestring',
 b: 42,
 c: false
};

console.log(Object.values(object1));

คุณจะได้รับอาร์เรย์ต่อไปนี้:

[ 'somestring', 42, false ]

ดังนั้นหากคุณต้องการเข้าถึงobject1.bแต่ใช้ดัชนีแทนคุณสามารถใช้:

Object.values(object1)[1] === 42

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวิธีการนี้ที่นี่


1
วิธีนี้ภายในคำแนะนำในหัวข้อนี้ดูเหมือนจะสั้นและสง่างามที่สุด
Petro Franko

5
var obj = {
    'key1':'value',
    '2':'value',
    'key 1':'value'
}

console.log(obj.key1)
console.log(obj['key1'])
console.log(obj['2'])
console.log(obj['key 1'])

// will not work
console.log(obj.2)

แก้ไข:

"ฉันต้องการกำหนดเป้าหมายดัชนีโดยเฉพาะเช่นเดียวกับตัวอย่างแรก - ถ้าเป็นไปได้"

จริงๆแล้ว 'ดัชนี' เป็นกุญแจสำคัญ หากคุณต้องการจัดเก็บตำแหน่งของคีย์คุณต้องสร้างวัตถุที่กำหนดเองเพื่อจัดการสิ่งนี้


ฉันรู้ว่าคุณสามารถเข้าถึงได้ด้วยกุญแจนั่นไม่ใช่สิ่งที่ฉันขอ
daryl

@ โปรแกรมเมอร์: คำถามของคุณคลุมเครือดังนั้นโพสต์นี้อาจตอบคำถามตามที่เขียนไว้
ออก


2

รับอาร์เรย์ของคีย์ย้อนกลับจากนั้นเรียกใช้ลูปของคุณ

  var keys = Object.keys( obj ).reverse();
  for(var i = 0; i < keys.length; i++){
    var key = keys[i];
    var value = obj[key];
    //do stuff backwards
  }

1

คุณสามารถสร้างอาร์เรย์ที่เต็มไปด้วยฟิลด์วัตถุของคุณและใช้ดัชนีในอาร์เรย์และเข้าถึงคุณสมบัติของวัตถุผ่านทางนั้น

propertiesName:['pr1','pr2','pr3']

this.myObject[this.propertiesName[0]]

1

ฉันไปข้างหน้าและสร้างฟังก์ชันให้คุณ:

 Object.prototype.getValueByIndex = function (index) {
     /*
         Object.getOwnPropertyNames() takes in a parameter of the object, 
         and returns an array of all the properties.
         In this case it would return: ["something","evenmore"].
         So, this[Object.getOwnPropertyNames(this)[index]]; is really just the same thing as:
         this[propertyName]
    */
    return this[Object.getOwnPropertyNames(this)[index]];
};

let obj = {
    'something' : 'awesome',
    'evenmore'  : 'crazy'
};

console.log(obj.getValueByIndex(0)); // Expected output: "awesome"


1
คุณช่วยอธิบายสิ่งที่กำลังทำในแนวทางของคุณได้ไหม?
Rahul Bhobe

ฉันได้เพิ่มความคิดเห็นในโค้ดเพื่อให้คุณเข้าใจว่ากำลังทำอะไรอยู่
StackGeek

0

หากคุณไม่แน่ใจว่า Object.keys () จะส่งคืนคีย์ให้คุณในลำดับที่ถูกต้องคุณสามารถลองใช้ตรรกะนี้แทน

var keys = []
var obj = {
    'key1' : 'value1',
    'key2' : 'value2',
    'key3' : 'value3',
}
for (var key in obj){
    keys.push(key)
}
console.log(obj[keys[1]])
console.log(obj[keys[2]])
console.log(obj[keys[3]])
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.