Làm cách nào để có được tất cả các giá trị thuộc tính của Đối tượng JavaScript (mà không cần biết các khóa)?


455

Nếu có một đối tượng Javascript:

var objects={...};

Giả sử, nó có hơn 50 thuộc tính, mà không biết tên thuộc tính (mà không biết 'khóa') làm thế nào để có được mỗi giá trị thuộc tính trong một vòng lặp?


23
Lưu ý cho độc giả: đừng 'bỏ lỡ câu trả lời thứ hai
Pandaiolo

Câu trả lời:


447

Bằng cách sử dụng một for..invòng lặp đơn giản :

for(var key in objects) {
    var value = objects[key];
}

90
Hãy cẩn thận về các thuộc tính của đối tượng nguyên mẫu được kế thừa. Xem: hasOwnProperty ()
ô liu

102
Nếu bạn đang đọc câu trả lời này, bạn chắc chắn nên đọc câu trả lời khác
mgarciaisaia

18
Nếu bạn đang đọc câu trả lời này và bạn có thể xử lý các chuỗi, bạn chắc chắn nên đấm vào mặt javascript.

Nếu bạn đọc câu trả lời ở trên và muốn đấm vào mặt JavaScript, hãy thử lodash
slugmandrew

Có lẽ nên chỉ ra rằng điều này sẽ KHÔNG bao gồm các thuộc tính có enumerablecờ của chúng được đặt thành false. Điều này - trong số những thứ khác - có nghĩa là bạn sẽ không lặp lại bất kỳ phương thức lớp nào, nhưng bạn sẽ lặp lại các phương thức được tạo theo các cách khác.
người làm giàu giàu có

1012

Tùy thuộc vào trình duyệt nào bạn phải hỗ trợ, việc này có thể được thực hiện theo một số cách. Phần lớn các trình duyệt trong hỗ trợ tự nhiên ECMAScript 5 (ES5), nhưng được cảnh báo rằng nhiều ví dụ dưới đây sử dụngObject.keys , không có sẵn trong IE <9. Xem bảng tương thích .

ECMAScript 3+

Nếu bạn phải hỗ trợ các phiên bản IE cũ hơn, thì đây là tùy chọn dành cho bạn:

for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        var val = obj[key];
        // use val
    }
}

Lồng nhau if đảm bảo rằng bạn không liệt kê các thuộc tính trong chuỗi nguyên mẫu của đối tượng (đó là hành vi mà bạn gần như chắc chắn muốn). Bạn phải dùng

Object.prototype.hasOwnProperty.call(obj, key) // ok

thay vì

obj.hasOwnProperty(key) // bad

bởi vì ECMAScript 5+ cho phép bạn tạo các đối tượng không nguyên mẫu Object.create(null)và các đối tượng này sẽ không cóhasOwnProperty phương thức. Mã nghịch ngợm cũng có thể tạo ra các đối tượng ghi đè hasOwnPropertyphương thức.

ECMAScript 5+

Bạn có thể sử dụng các phương thức này trong bất kỳ trình duyệt nào hỗ trợ ECMAScript 5 trở lên. Chúng nhận các giá trị từ một đối tượng và tránh liệt kê qua chuỗi nguyên mẫu. objĐối tượng của bạn ở đâu :

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {
    var val = obj[keys[i]];
    // use val
}

Nếu bạn muốn một cái gì đó nhỏ gọn hơn một chút hoặc bạn muốn cẩn thận với các chức năng trong các vòng lặp, thì đó Array.prototype.forEachlà bạn của bạn:

Object.keys(obj).forEach(function (key) {
    var val = obj[key];
    // use val
});

Phương thức tiếp theo xây dựng một mảng chứa các giá trị của một đối tượng. Điều này là thuận tiện cho vòng lặp qua.

var vals = Object.keys(obj).map(function (key) {
    return obj[key];
});

// use vals array

Nếu bạn muốn làm cho những người sử dụng Object.keysan toàn chống lại null(như for-inhiện tại), thì bạn có thể làm Object.keys(obj || {})....

Object.keyslợi nhuận đếm tài sản. Để lặp qua các đối tượng đơn giản, điều này thường là đủ. Nếu bạn có một cái gì đó với các thuộc tính không thể đếm được mà bạn cần phải làm việc với, bạn có thể sử dụng Object.getOwnPropertyNamesthay choObject.keys .

ECMAScript 2015+ (AKA ES6)

Mảng dễ lặp lại hơn với ECMAScript 2015. Bạn có thể sử dụng điều này để lợi thế của bạn khi làm việc với các giá trị từng bước một trong vòng lặp:

for (const key of Object.keys(obj)) {
    const val = obj[key];
    // use val
}

Sử dụng các hàm mũi tên béo ECMAScript 2015, ánh xạ đối tượng vào một mảng các giá trị sẽ trở thành một lớp lót:

const vals = Object.keys(obj).map(key => obj[key]);

// use vals array

ECMAScript 2015 giới thiệu Symbol, các trường hợp có thể được sử dụng làm tên thuộc tính. Để lấy các ký hiệu của một đối tượng để liệt kê, hãy sử dụng Object.getOwnPropertySymbols(chức năng này là lý do tại sao Symbol không thể được sử dụng để tạo các thuộc tính riêng tư). ReflectAPI mới từ ECMAScript 2015 cung cấp Reflect.ownKeys, trả về danh sách các tên thuộc tính (bao gồm cả tên không thể liệt kê) và các ký hiệu.

Hiểu mảng (không cố sử dụng)

Hiểu mảng đã bị xóa khỏi ECMAScript 6 trước khi xuất bản. Trước khi loại bỏ chúng, một giải pháp sẽ có vẻ như:

const vals = [for (key of Object.keys(obj)) obj[key]];

// use vals array

ECMAScript 2017+

ECMAScript 2016 bổ sung các tính năng không ảnh hưởng đến chủ đề này. Đặc điểm kỹ thuật ECMAScript 2017 thêm Object.valuesObject.entries. Cả hai mảng trả về (sẽ gây ngạc nhiên cho một số tương tự với Array.entries). Object.valuescó thể được sử dụng như là hoặc với mộtfor-of vòng lặp.

const values = Object.values(obj);

// use values array or:

for (const val of Object.values(obj)) {
    // use val
}

Nếu bạn muốn sử dụng cả khóa và giá trị, thì đó Object.entrieslà dành cho bạn. Nó tạo ra một mảng chứa đầy [key, value]các cặp. Bạn có thể sử dụng điều này như là, hoặc (lưu ý cả nhiệm vụ hủy diệt ECMAScript 2015) trong một for-ofvòng lặp:

for (const [key, val] of Object.entries(obj)) {
    // use key and val
}

Object.values shim

Cuối cùng, như đã lưu ý trong các bình luận và bởi teh_senaus trong một câu trả lời khác, có thể đáng để sử dụng một trong số này như một shim. Đừng lo lắng, sau đây không thay đổi nguyên mẫu, nó chỉ thêm một phương thức vào Object(ít nguy hiểm hơn nhiều). Sử dụng các hàm mũi tên béo, điều này cũng có thể được thực hiện trong một dòng:

Object.values = obj => Object.keys(obj).map(key => obj[key]);

mà bây giờ bạn có thể sử dụng như

// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });

Nếu bạn muốn tránh làm mờ khi bản địa Object.valuestồn tại, thì bạn có thể làm:

Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));

Cuối cùng ...

Hãy nhận biết các trình duyệt / phiên bản bạn cần hỗ trợ. Trên đây là chính xác nơi các phương thức hoặc tính năng ngôn ngữ được thực hiện. Ví dụ: hỗ trợ cho ECMAScript 2015 đã bị tắt theo mặc định trong V8 cho đến gần đây, hỗ trợ cho các trình duyệt như Chrome. Nên tránh các tính năng từ ECMAScript 2015 cho đến khi các trình duyệt bạn định hỗ trợ triển khai các tính năng mà bạn cần. Nếu bạn sử dụng babel để biên dịch mã của bạn thành ECMAScript 5, thì bạn có quyền truy cập vào tất cả các tính năng trong câu trả lời này.


9
Đây phải là câu trả lời được chấp nhận (hoặc ít nhất là nâng cao hơn) vì câu trả lời được chấp nhận là không đầy đủ (@olive chỉ ra điều này).
0xc0de

Thật xấu hổ vì tất cả những mánh khóe được gọi là, chúng ta vẫn cần đề cập đến objhai lần. Tôi đoán việc tạo ra một chức năng trợ giúp là không thể tránh khỏi? Một cái gì đó như giá trị (obj).
Steven Haryanto

Bất kỳ phương pháp nào trong số này có thể được sử dụng như một shim. Ví dụ:Object.values = obj => Object.keys(obj).map(key => obj[key]);
qubyte

1
Các giải pháp ECMA 5 sẽ hoạt động trong tất cả các trình duyệt hiện đại. ECMA 6 vẫn chưa được hoàn thiện và hỗ trợ là sơ bộ trong tất cả các trình duyệt. Trong Chrome, ECMA 6 được triển khai một phần nhưng bị vô hiệu hóa. Trong Firefox, sự hỗ trợ tốt hơn nhưng việc hiểu mảng là sai (như đã đề cập). Tôi nghĩ rằng việc tôi sử dụng thì tương lai sẽ ám chỉ điều này. @JacekLampart, giải pháp nào cho bạn lỗi?
qubyte

2
Tôi không thể tưởng tượng được tại sao chúng ta phải đợi ES2017 để có được phương thức Object.values ​​().
Herbertusz

31

Đây là một chức năng có thể tái sử dụng để nhận các giá trị vào một mảng. Nó có nguyên mẫu vào tài khoản quá.

Object.values = function (obj) {
    var vals = [];
    for( var key in obj ) {
        if ( obj.hasOwnProperty(key) ) {
            vals.push(obj[key]);
        }
    }
    return vals;
}

15
Sửa đổi Objectkhông phải là vấn đề lớn ( Object.keyslà một shim phổ biến), có lẽ bạn đang nghĩ đến việc sửa đổi nguyên mẫu Object.
sandstrom

Tại sao bạn cần phải thử nghiệm với hasOwnProperty()? Làm thế nào khóa được lặp đi lặp lại trong vòng lặp của đối tượng đó không có thuộc tính?
1252748

4
Google nó @thomas, nó quan trọng. Nó có thể có các thuộc tính từ chuỗi nguyên mẫu của nó.
Joe

28

Nếu bạn có quyền truy cập vào Underscore.js, bạn có thể sử dụng _.valueschức năng như thế này:

_.values({one : 1, two : 2, three : 3}); // return [1, 2, 3]

@MathieuAmiot - quan tâm giải thích?
Paden

lodash là một sự thay thế tương thích api cho gạch dưới, một (cách) nhanh hơn.
Mathieu Amiot

@Paden đây là một câu hỏi liên quan trên SO: stackoverflow.com/questions/13789618/
triệt

2
lodash là không cần thiết cho việc này và sẽ làm
mờ

14

Nếu bạn thực sự muốn một mảng Giá trị, tôi thấy điều này sạch hơn là xây dựng một mảng với vòng lặp for ....

ECMA 5.1+

function values(o) { return Object.keys(o).map(function(k){return o[k]}) }

Điều đáng chú ý là trong hầu hết các trường hợp, bạn không thực sự cần một mảng các giá trị, sẽ nhanh hơn để làm điều này:

for(var k in o) something(o[k]);

Điều này lặp đi lặp lại trên các phím của Object o. Trong mỗi lần lặp k được đặt thành một khóa của o.


9

ES5 Object.keys

var a = { a: 1, b: 2, c: 3 };
Object.keys(a).map(function(key){ return a[key] });
// result: [1,2,3]

3
Tại sao điều này đã bị hạ cấp? Tôi muốn nói rằng đây là một trong những giải pháp sạch nhất.
Sebastian Hojas

Tôi không biết, tại sao điều này lại bỏ phiếu. Đây là giải pháp đơn giản và thuần túy nhất trong js mà không cần sử dụng bất kỳ thư viện hoặc bất kỳ tiện ích nào khác.
sanjeev shetty

5

Bạn có thể lặp qua các phím:

foo = {one:1, two:2, three:3};
for (key in foo){
    console.log("foo["+ key +"]="+ foo[key]);
}

sẽ xuất ra:

foo[one]=1
foo[two]=2
foo[three]=3

2
Bạn cũng cần kiểm tra `hasOwnProperty () 'nếu bạn muốn tránh các thuộc tính được kế thừa.
0xc0de

3

Đối với những người thích nghi sớm với kỷ nguyên CofeeScript, đây là một cách tương đương khác.

val for key,val of objects

Điều này có thể tốt hơn điều này bởi vì objectscó thể được giảm để gõ lại và giảm khả năng đọc.

objects[key] for key of objects

3

sử dụng một polyfill như:

if(!Object.values){Object.values=obj=>Object.keys(obj).map(key=>obj[key])}

sau đó sử dụng

Object.values(my_object)

3) lợi nhuận!



2

Rõ ràng - như tôi mới biết - đây là cách nhanh nhất để làm điều đó:

var objs = {...};
var objKeys = Object.keys(obj);
for (var i = 0, objLen = objKeys.length; i < objLen; i++) {
    // do whatever in here
    var obj = objs[objKeys[i]];
}

bạn có thể đặt một codepen hoặc jsfiddle của một ví dụ về điều này? cảm ơn.
Chris22

2

Câu hỏi không xác định liệu muốn sở hữu các thuộc tính thừa kế và không liệt kê hay không.

một câu hỏi để có được mọi thứ, các thuộc tính được thừa kế và các thuộc tính không thể đếm được cũng , mà Google không thể dễ dàng tìm thấy.

Giải pháp của tôi cho điều đó là:

function getAllPropertyNames(obj) {
    let result = new Set();
    while (obj) {
        Object.getOwnPropertyNames(obj).forEach(p => result.add(p));
        obj = Object.getPrototypeOf(obj);
    }
    return [...result];
}

Và sau đó lặp lại chúng, chỉ cần sử dụng vòng lặp for:


1

Sử dụng: Object.values() , chúng ta truyền vào một đối tượng làm đối số và nhận một mảng các giá trị dưới dạng giá trị trả về.

Điều này trả về một mảng của một đối tượng nhất định sở hữu các giá trị thuộc tính. Bạn sẽ nhận được các giá trị giống như bằng cách sử dụng for invòng lặp nhưng không có các thuộc tính trên Nguyên mẫu. Ví dụ này có thể sẽ làm cho mọi thứ rõ ràng hơn:

function person (name) {
  this.name = name;
}

person.prototype.age = 5;

let dude = new person('dude');

for(let prop in dude) {
  console.log(dude[prop]);     // for in still shows age because this is on the prototype
}                              // we can use hasOwnProperty but this is not very elegant

// ES6 + 
console.log(Object.values(dude));
// very concise and we don't show props on prototype


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

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

// expected output:
// "a: somestring"
// "b: 42"
// order is not guaranteed

0

Đây là một hàm tương tự như Array_values ​​() của PHP

function array_values(input) {
  var output = [], key = '';
  for ( key in input ) { output[output.length] = input[key]; }
  return output;
}

Đây là cách nhận các giá trị của đối tượng nếu bạn đang sử dụng ES6 trở lên:

Array.from(values(obj));

Vì một số lý do, giá trị () đang hoạt động trong Chrome và Firefox, nhưng không phải trên iojs / nút.
jaggedsoft

0

Tương thích với ES7 thậm chí một số trình duyệt chưa hỗ trợ

Vì, Object.values(<object>)sẽ được tích hợp sẵn trong ES7 &

Cho đến khi chờ tất cả các trình duyệt hỗ trợ nó, bạn có thể gói nó bên trong một chức năng:

Object.vals=(o)=>(Object.values)?Object.values(o):Object.keys(o).map((k)=>o[k])

Sau đó :

Object.vals({lastname:'T',firstname:'A'})
 // ['T','A']

Khi các trình duyệt tương thích với ES7, bạn sẽ không phải thay đổi bất cứ điều gì trong mã của mình.


0

Tôi nhận ra tôi là muộn một chút nhưng đây là một shim cho cái mới firefox 47 Object.valuesphương pháp

Object.prototype.values = Object.prototype.values || function(obj) {
  return this.keys(obj).map(function(key){
    return obj[key];
  });
};

0

Object.entries làm điều đó theo cách tốt hơn.

  var dataObject = {"a":{"title":"shop"}, "b":{"title":"home"}}
 
   Object.entries(dataObject).map(itemArray => { 
     console.log("key=", itemArray[0], "value=", itemArray[1])
  })


0

const myObj = { a:1, b:2, c:3 }

Nhận tất cả các giá trị:

  • con đường ngắn nhất:

    • const myValues = Object.values(myObj)
  • const myValues = Object.keys(myObj).map(key => myObj[key])


-1
var objects={...}; this.getAllvalues = function () {
        var vls = [];
        for (var key in objects) {
            vls.push(objects[key]);
        }
        return vls;
    }

-5

trong ECMAScript5 sử dụng

 keys = Object.keys(object);

Nếu không, nếu trình duyệt của bạn không hỗ trợ nó, hãy sử dụng trình duyệt nổi tiếng for..in loop

for (key in object) {
    // your code here
}

17
Câu hỏi là yêu cầu các giá trị, không phải các khóa.
zachelrath

@zachelrath Bạn nói đúng. - Nhưng tập lệnh này hữu ích nếu bạn muốn lấy các giá trị vì khi bạn biết các khóa bạn có thể sử dụng object[key]để lấy các giá trị trong một vòng lặp.
fridojet

2
@fridojet Nhưng điều đó có thể được thực hiện với for..in(và hasOwnProperty) vì vậy nó không thực sự đạt được bất cứ điều gì .. Tôi ước rằng ECMAScript 5 được định nghĩa Object.pairs(và Object.itemscho [[key, value], ..]), nhưng than ôi, nó không.
dùng2246674

-8

Bây giờ tôi sử dụng Bộ công cụ Dojo vì các trình duyệt cũ hơn không hỗ trợ Object.values.

require(['dojox/lang/functional/object'], function(Object) {
    var obj = { key1: '1', key2: '2', key3: '3' };
    var values = Object.values(obj);
    console.log(values);
});

Đầu ra:

['1', '2', '3']

5
Nói đúng ra, mảng không đúng. Bạn có một chuỗi các chuỗi thay vì một mảng các số.
qubyte

-10

sử dụng

console.log(variable)

và nếu bạn sử dụng google chrome mở Bảng điều khiển bằng cách sử dụng Ctrl + Shift + j

Goto >> Bảng điều khiển

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.