รับกุญแจของวัตถุมากมาย


371

ฉันต้องการได้รับคีย์ของวัตถุ JavaScript เป็นอาร์เรย์ทั้งใน jQuery หรือ JavaScript บริสุทธิ์

มีวิธี verbose น้อยกว่านี้ไหม

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}

4
นอกเหนือจากการเพิ่มif(foo.hasOwnProperty(key))นั่นคือสิ่งที่ฉันจะทำ $.mapหรือใช้
Rocket Hazmat

10
โอ้สำหรับ Pythonic หนึ่งซับ แต่ ...
ริชาร์ด

คำถามเก่าจึงไม่คุ้มค่าคำตอบเต็มรูปแบบ แต่สำหรับผู้ที่ต้องการซอ ... jsfiddle.net/LR5D9/3วิธีการแก้ปัญหานี้เกี่ยวข้องกับปัญหาของการประกาศต้นแบบ messing up for var in xลูป
unsynchronized

คำตอบ:


618

การใช้Object.keys:

var foo = {
  'alpha': 'puffin',
  'beta': 'beagle'
};

var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta'] 
// (or maybe some other order, keys are unordered).

นี่คือคุณสมบัติ ES5 ซึ่งหมายความว่ามันทำงานในเบราว์เซอร์ที่ทันสมัย แต่จะไม่ทำงานในเบราว์เซอร์มรดก

ES5-shim มีการนำไปใช้ของObject.keysคุณที่สามารถขโมยได้


5
หมายเหตุ: ใช้งานได้กับเบราว์เซอร์รุ่นใหม่เท่านั้น (โดยที่ฉันหมายถึงไม่ใช่ IE <9)
Rocket Hazmat

2
แล้วเบราว์เซอร์มือถือล่ะ?
Marwen Trabelsi

1
@SmartyTwiti: ฉันไม่แน่ใจ ฉันคิดว่ามันเหมือน Chrome หรือ Firefox
Rocket Hazmat

MDN ยังมี Polyfill ที่อ้างถึงข้างต้น แต่บันทึกข้อบกพร่องใน IE7 และอาจจะ 8 จากนั้นอ้างถึง Polyfill ที่สั้นกว่ามากที่นี่: tokenposts.blogspot.com.au/2012/04/55
Campbeln

ดังนั้นเราจะทำสิ่งนี้ก่อน ES5 ได้อย่างไร?
Andrew S


33

แน่นอนว่าObject.keys()เป็นวิธีที่ดีที่สุดในการรับกุญแจของวัตถุ ถ้ามันไม่สามารถใช้ได้ในสภาพแวดล้อมของคุณก็สามารถนิดshimmedใช้รหัสเช่นในตัวอย่างของคุณ (ยกเว้นคุณจะต้องคำนึงถึงห่วงของคุณจะย้ำกว่าคุณสมบัติทั้งหมดขึ้นห่วงโซ่ต้นแบบซึ่งแตกต่างจากObject.keys()พฤติกรรม)

อย่างไรก็ตามรหัสตัวอย่างของคุณ ...

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}

jsFiddle

... สามารถแก้ไขได้ คุณสามารถทำงานที่ได้รับมอบหมายในส่วนของตัวแปร

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i++] in foo) {}

jsFiddle

แน่นอนพฤติกรรมนี้แตกต่างจากสิ่งที่ทำObject.keys()จริง ( jsFiddle ) คุณสามารถใช้shim กับเอกสาร MDNได้


8
ฉันชอบสิ่งนี้var keys = [], i = 0; for (keys[i++] in foo) {}+1
Jashwant

ฉันได้ยินมาว่า "สำหรับใน" ไม่รับประกันการสั่งซื้อคุณรู้หรือไม่ว่า Object.keys ทำ
Chris Stephens

@ChrisStephens ไม่รับประกันการสั่งซื้อแม้ว่ากุญแจจะอยู่ในลำดับที่สั่ง
alex

2
โซลูชันทั้งหมดเหล่านี้ต้องการการhasOwnProperty()ตรวจสอบใช่ไหม?
ไนซ์

1
@TIMINeutron ไม่มีเหตุผลว่าทำไมมันไม่ควร :)
alex

7

ฉันไม่รู้เกี่ยวกับ verbose น้อยลง แต่ฉันได้รับแรงบันดาลใจให้บีบบังคับต่อไปนี้ในหนึ่งบรรทัดโดยการร้องขอแบบซับไลน์ไม่รู้ว่า Pythonic เป็นอย่างไร;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);

3
อาจจะเป็นvar enumerableKeysOnThePrototypeChain;)
alex

1
บางทีเราฉลาดพอที่จะรู้ว่าเราไม่ต้องกังวลกับ hasOwnProperty หากวัตถุนั้นถูกสร้างขึ้นภายใต้ขอบเขตของเราแทนที่จะนำเข้าจากที่อื่น
Dexygen

ไม่เหมือน pythonic เหมือนกับคำตอบที่ 2 ของ @ alex ( for (keys[i++] in foo) {}) เนื่องจากคุณยังคงทำงานอยู่Array.push()(ไม่ต้องพูดถึงการประกาศฟังก์ชันทั้งหมด) การดำเนินการแบบ pythonic ควรพึ่งพาความเข้าใจโดยนัยเท่าที่จะทำได้และความล้มเหลวนั้นโดยใช้การแสดงออกแลมบ์ดา
cowbert

4

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

const getObjectKeys = (obj, prefix = '') => {
  return Object.entries(obj).reduce((collector, [key, val]) => {
    const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
    if (Object.prototype.toString.call(val) === '[object Object]') {
      const newPrefix = prefix ? `${prefix}.${key}` : key
      const otherKeys = getObjectKeys(val, newPrefix)
      return [ ...newKeys, ...otherKeys ]
    }
    return newKeys
  }, [])
}

console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}}))


1

สรุป

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

ตัวอย่าง:

const object = {
  a: 'string1',
  b: 42,
  c: 34
};

const keys = Object.keys(object)

console.log(keys);

console.log(keys.length) // we can easily access the total amount of properties the object has

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

รับค่าด้วย: Object.values()

ฟังก์ชั่นเสริมของมีObject.keys() Object.values()ฟังก์ชั่นนี้ใช้วัตถุเป็นอาร์กิวเมนต์และส่งกลับอาร์เรย์ของค่า ตัวอย่างเช่น:

const object = {
  a: 'random',
  b: 22,
  c: true
};


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


1

หากคุณตัดสินใจที่จะใช้ Underscore.js คุณควรทำ

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.