Làm cách nào để truy cập các thuộc tính của đối tượng javascript nếu tôi không biết tên?


124

Giả sử bạn có một đối tượng javascript như thế này:

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

Bạn có thể truy cập các thuộc tính bằng tên thuộc tính:

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

Nhưng có thể có được các giá trị này nếu bạn không biết tên của các thuộc tính? Có phải bản chất không có thứ tự của các tính chất này làm cho chúng không thể phân biệt chúng?

Trong trường hợp của tôi, tôi đang nghĩ cụ thể về một tình huống trong đó một hàm cần chấp nhận một loạt các cặp giá trị tên, nhưng tên của các thuộc tính có thể thay đổi.

Suy nghĩ của tôi về cách thực hiện điều này cho đến nay là chuyển tên của các thuộc tính cho hàm cùng với dữ liệu, nhưng cảm giác này giống như một bản hack. Tôi muốn làm điều này với sự hướng nội nếu có thể.

Câu trả lời:


144

Bạn có thể lặp qua các phím như thế này:

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

Nhật ký này "Tên" và "Giá trị".

Nếu bạn có một loại đối tượng phức tạp hơn (không chỉ là một đối tượng giống như hàm băm đơn giản, như trong câu hỏi ban đầu), bạn sẽ chỉ muốn lặp qua các khóa thuộc về chính đối tượng, trái ngược với các khóa trên nguyên mẫu của đối tượng :

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

Như bạn đã lưu ý, các khóa không được đảm bảo theo bất kỳ thứ tự cụ thể nào. Lưu ý cách này khác với những điều sau đây:

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

Ví dụ này lặp qua các giá trị, vì vậy nó sẽ đăng nhập Property Name0. NB: for eachCú pháp chủ yếu chỉ được hỗ trợ trong Firefox, nhưng không có trong các trình duyệt khác.

Nếu trình duyệt mục tiêu của bạn hỗ trợ ES5 hoặc trang web của bạn bao gồm es5-shim.js(được khuyến nghị), bạn cũng có thể sử dụng Object.keys:

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

và lặp với Array.prototype.forEach:

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

Bạn đã làm cho cái cuối cùng lên và thực sự đã đi với nó? Làm tốt lắm ... =)
nickl-

Điều này tồn tại trong Firefox ( tài liệu ), nhưng điểm công bằng là nó không phổ biến. Tôi sẽ cập nhật câu trả lời để đề cập đến điều này.
Ron DeVera

28
btw alert là một cách tồi để gỡ lỗi mọi thứ, hãy thử console.log
StackOverflowed

Đây là câu trả lời tốt nhất khi câu hỏi được hỏi, nhưng tôi đang xóa dấu kiểm vì các phiên bản JS sau này đã cung cấp các công cụ tốt hơn.
Adam Lassek

65

Các phiên bản cũ của JavaScript (<ES5) yêu cầu sử dụng for..invòng lặp:

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

ES5 giới thiệu Object.keysArray # forEach , điều này làm cho việc này dễ dàng hơn một chút:

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 giới thiệu Object.valuesObject.entries.

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

1
Bây giờ điều này thực sự trả lời câu hỏi, được thực hiện tốt @Adam Lassek, được thực hiện rất độc đáo.
nickl-

Thật sai lầm khi sử dụng cả 'tên' và 'giá trị' làm khóa đối tượng. Hàm này chỉ trả về các khóa trong danh sách, không phải các giá trị. {name1: 'value1', name2: 'value2'} sẽ tránh nhầm lẫn cho người mới bắt đầu. Object.keys (dữ liệu); // ['name1', 'name2']
James Nicholson

2
@JamesNicholson Tôi đồng ý, chỉnh sửa để bớt khó hiểu.
Adam Lassek


4

Bạn thường sẽ muốn kiểm tra các thuộc tính cụ thể của một thể hiện của một đối tượng, mà không có tất cả các phương thức và thuộc tính nguyên mẫu chung của nó:

 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;
}

Điều này sẽ nhận được tất cả các thuộc tính và giá trị của chúng (được kế thừa hoặc sở hữu, có thể đếm được hoặc không) trong một đối tượng mới. đối tượng ban đầu là không bị ảnh hưởng. Bây giờ đối tượng mới có thể được duyệt qua bằng cách sử dụng

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
}

trong đó câu trả lời này cung cấp những gì được OP yêu cầu nhưng một mô tả nhỏ về những gì bạn đang làm và tại sao OP nên sử dụng nó sẽ tốt, cũng đừng quên .hasOwnProperty()khi sử dụng để lặp lại một đối tượng.
Muhammad Omer Aslam

Cảm ơn, tôi đồng ý rằng .hasOwnProperty () lặp lại đối tượng nhưng nó lặp đi lặp lại để kiểm tra một điều kiện tuy nhiên khi sử dụng nó, chúng ta không thể in tất cả các thuộc tính của một đối tượng. Sửa tôi nếu tôi sai.
Mayank_VK

Các hasOwnProperty()trở về phương pháp một booleanchỉ thị cho dù đối tượng có tính chất xác định là tài sản riêng của mình (như trái ngược với kế thừa nó) . xem ví dụ
Muhammad Omer Aslam

1

Bạn có thể sử dụng Object.keys () , "trả về một mảng các tên thuộc tính có thể đếm được của chính đối tượng đã cho, theo thứ tự như chúng ta nhận được với một vòng lặp thông thường."

Bạn có thể sử dụng bất kỳ đối tượng nào thay cho 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]);
}


Bạn có thể thêm lời giải thích?
Keith Pinson

Object.keys( stats )[key]làm cho không có ý nghĩa, sẽ luôn luôn được 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

Điều này không thêm gì vào câu trả lời được chấp nhận và trình bày thông tin theo cách ít hữu ích nhất có thể. Và nó không chiếm tài sản thừa kế.
Adam Lassek
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.