Nhận mảng các khóa của đối tượng


371

Tôi muốn lấy các khóa của một đối tượng JavaScript dưới dạng một mảng, trong jQuery hoặc JavaScript thuần.

Có một cách ít dài dòng hơn thế này?

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

4
Ngoài việc thêm vào if(foo.hasOwnProperty(key)), đó là những gì tôi sẽ làm. Hoặc, sử dụng $.map.
Tên lửa Hazmat

10
Ồ, cho một lớp lót Pythonic, mặc dù ...
Richard

một câu hỏi cũ không đáng để trả lời đầy đủ, nhưng đối với những người muốn tìm hiểu ... jsfiddle.net/LR5D9/3 giải pháp này liên quan đến vấn đề khai báo nguyên mẫu làm rối for var in xcác vòng lặp
không đồng bộ hóa vào

Câu trả lời:


618

Sử dụng 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).

Đây là một tính năng ES5. Điều này có nghĩa là nó hoạt động trong tất cả các trình duyệt hiện đại nhưng sẽ không hoạt động trong các trình duyệt cũ .

ES5-shim có triển khai Object.keysbạn có thể đánh cắp


5
Lưu ý: Điều này chỉ hoạt động trên các trình duyệt hiện đại (ý tôi là không phải IE <9).
Tên lửa Hazmat

2
Còn trình duyệt di động thì sao?
Marwen Trabelsi

1
@SmartyTwiti: Tôi không chắc. Tôi cho rằng nó hoạt động như Chrome hoặc Firefox.
Tên lửa Hazmat

MDN cũng có gọi Polyfill trên, nhưng ghi chú lỗi trong IE7 và có lẽ 8, sau đó đề cập tắt vào một Polyfill ngắn hơn nhiều ở đây: tokenposts.blogspot.com.au/2012/04/...
Campbeln

Vậy làm thế nào một người làm điều này trước ES5?
Andrew S

59

Bạn có thể sử dụng jQuery $.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});

Hoặc each, nếu bạn đang làm gì đó với họ. $.each(foo, function(index, value){/* do something with index */});
Chris

33

Tất nhiên, Object.keys()là cách tốt nhất để lấy các khóa của Object. Nếu nó không có sẵn trong môi trường của bạn, nó có thể bị lung lay một cách tầm thường bằng cách sử dụng mã như trong ví dụ của bạn (ngoại trừ bạn cần tính đến vòng lặp của mình sẽ lặp lại tất cả các thuộc tính trong chuỗi nguyên mẫu, không giống như Object.keys()hành vi của chuỗi ).

Tuy nhiên, mã ví dụ của bạn ...

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

jsFiddle .

... Có thể được sửa đổi. Bạn có thể làm bài tập ngay trong phần biến .

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

jsFiddle .

Tất nhiên, hành vi này khác với những gì Object.keys()thực sự làm ( jsFiddle ). Bạn chỉ có thể sử dụng shim trên tài liệu MDN .


8
Tôi thích var keys = [], i = 0; for (keys[i++] in foo) {}+1 này
Jashwant

Tôi nghe nói rằng "for in" không đảm bảo trật tự, bạn có biết Object.keys không?
Chris Stephens

@ChrisStephens Không đảm bảo trật tự, ngay cả khi các khóa cuối cùng nằm trong một mảng được đặt hàng.
alex

2
Tất cả những giải pháp này cần hasOwnProperty()kiểm tra, chắc chắn?
không đồng bộ

1
@TIMINeutron Không có lý do tại sao nó không nên :)
alex

7

Tôi không biết về ít dài dòng hơn nhưng tôi được truyền cảm hứng để ép buộc những điều sau vào một dòng theo yêu cầu một lớp, không biết Pythonic là như thế nào;)

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

3
Có lẽ nên như vậy var enumerableKeysOnThePrototypeChain;)
alex

1
Có lẽ chúng ta đủ thông minh để biết rằng chúng ta không phải lo lắng về hasOwnProperty nếu đối tượng được tạo hoàn toàn dưới tầm nhìn của chúng ta, trái ngược với việc được nhập từ một nơi khác
Dexygen

for (keys[i++] in foo) {}mặc dù không phải là pythonic như câu trả lời thứ 2 của @ alex ( ), bởi vì bạn vẫn đang thực hiện Array.push()(không đề cập đến việc khai báo toàn bộ chức năng). Việc thực hiện pythonic nên dựa nhiều vào sự hiểu biết ngầm càng tốt và không thực hiện được điều đó, bằng cách sử dụng biểu thức lambda.
cowbert

4

Trong trường hợp bạn đang ở đây để tìm kiếm một cái gì đó để liệt kê các khóa của một đối tượng lồng nhau có độ sâu n dưới dạng một mảng phẳng:

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

Tóm lược

Để lấy tất cả các khóa của một đối tượng bạn có thể sử dụng Object.keys(). Object.keys()lấy một đối tượng làm đối số và trả về một mảng của tất cả các khóa.

Thí dụ:

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

Trong ví dụ trên, chúng tôi lưu trữ một mảng các khóa trong các khóa const. Sau đó chúng ta có thể dễ dàng truy cập số lượng thuộc tính trên đối tượng bằng cách kiểm tra độ dài của mảng khóa.

Lấy các giá trị với: Object.values()

Các chức năng bổ sung của Object.keys()Object.values(). Hàm này lấy một đối tượng làm đối số và trả về một mảng các giá trị. Ví dụ:

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


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


1

Nếu bạn quyết định sử dụng Underscore.js, bạn nên làm

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
    keys.push(key);
});
console.log(keys);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.