it-swarm-vi.tech

Làm cách nào để liệt kê các thuộc tính của đối tượng JavaScript?

Làm cách nào để liệt kê các thuộc tính của đối tượng JavaScript?

Tôi thực sự muốn liệt kê tất cả các biến được xác định và các giá trị của chúng, nhưng tôi đã học được rằng việc xác định một biến thực sự tạo ra một thuộc tính của đối tượng cửa sổ.

630
davenpcj

Đủ đơn giản:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

Bây giờ, bạn sẽ không nhận được các biến riêng tư theo cách này vì chúng không có sẵn.


EDIT: @ bitwiseplatypus là chính xác, trừ khi bạn sử dụng phương thức hasOwnProperty(), bạn sẽ nhận được các thuộc tính được kế thừa - tuy nhiên, tôi không biết tại sao mọi người quen với lập trình hướng đối tượng sẽ mong đợi bất cứ điều gì ít hơn! Thông thường, ai đó đưa ra điều này đã phải chịu những cảnh báo của Douglas Crockford về điều này, điều này vẫn khiến tôi bối rối một chút. Một lần nữa, tính kế thừa là một phần bình thường của các ngôn ngữ OO và do đó là một phần của JavaScript, mặc dù nó là nguyên mẫu.

Bây giờ, điều đó nói rằng, hasOwnProperty() hữu ích cho việc lọc, nhưng chúng ta không cần phải cảnh báo như thể có gì đó nguy hiểm khi nhận các thuộc tính được thừa kế.

EDIT 2: @ bitwiseplatypus đưa ra tình huống sẽ xảy ra nếu ai đó thêm thuộc tính/phương thức vào các đối tượng của bạn tại một thời điểm muộn hơn so với khi ban đầu bạn viết đối tượng của mình (thông qua nguyên mẫu của nó ) - trong khi sự thật là điều này có thể gây ra hành vi bất ngờ, cá nhân tôi không xem đó là vấn đề của mình hoàn toàn. Chỉ là vấn đề quan điểm. Bên cạnh đó, điều gì sẽ xảy ra nếu tôi thiết kế mọi thứ theo cách mà tôi sử dụng các nguyên mẫu trong quá trình xây dựng các đối tượng của mình và vẫn có mã lặp lại các thuộc tính của đối tượng và tôi muốn tất cả các thuộc tính được kế thừa? Tôi sẽ không sử dụng hasOwnProperty(). Sau đó, giả sử, ai đó thêm các thuộc tính mới sau. Đó có phải là lỗi của tôi nếu mọi thứ hành xử tồi tệ vào thời điểm đó? Tôi không nghĩ vậy. Tôi nghĩ đây là lý do tại sao jQuery, như một ví dụ, đã chỉ định các cách mở rộng cách thức hoạt động của nó (thông qua jQuery.extendjQuery.fn.extend).

790
Jason Bunting

Sử dụng vòng lặp for..in để liệt kê các thuộc tính của đối tượng, nhưng hãy cẩn thận. Phép liệt kê sẽ trả về các thuộc tính không chỉ của đối tượng được liệt kê mà còn từ các nguyên mẫu của bất kỳ đối tượng cha nào.

var myObject = {foo: 'bar'};

for (var name in myObject) {
  alert(name);
}

// results in a single alert of 'foo'

Object.prototype.baz = 'quux';

for (var name in myObject) {
  alert(name);
}

// results in two alerts, one for 'foo' and one for 'baz'

Để tránh bao gồm các thuộc tính được kế thừa trong bảng liệt kê của bạn, hãy kiểm tra hasOwnProperty():

for (var name in myObject) {
  if (myObject.hasOwnProperty(name)) {
    alert(name);
  }
}

Chỉnh sửa : Tôi không đồng ý với tuyên bố của JasonBunting rằng chúng ta không cần phải lo lắng về việc liệt kê các tài sản được thừa kế. Có nguy hiểm khi liệt kê các thuộc tính được kế thừa mà bạn không mong đợi, bởi vì nó có thể thay đổi hành vi của mã của bạn.

Không thành vấn đề liệu vấn đề này có tồn tại trong các ngôn ngữ khác hay không; thực tế là nó tồn tại và JavaScript đặc biệt dễ bị tổn thương do việc sửa đổi nguyên mẫu của một đối tượng ảnh hưởng đến các đối tượng con ngay cả khi việc sửa đổi diễn ra sau khi khởi tạo.

Đây là lý do tại sao JavaScript cung cấp hasOwnProperty() và đây là lý do tại sao bạn nên sử dụng nó để đảm bảo rằng mã của bên thứ ba (hoặc bất kỳ mã nào khác có thể sửa đổi nguyên mẫu) không phá vỡ nguyên mẫu của bạn. Ngoài việc thêm một vài byte mã, không có nhược điểm nào khi sử dụng hasOwnProperty().

215
Ryan Grove

Cách tiêu chuẩn, đã được đề xuất nhiều lần là:

for (var name in myObject) {
  alert(name);
}

Tuy nhiên, Internet Explorer 6, 7 và 8 có lỗi trong trình thông dịch JavaScript, điều này có tác dụng là một số khóa không được liệt kê. Nếu bạn chạy mã này:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}

Nếu sẽ cảnh báo "12" trong tất cả các trình duyệt trừ IE. IE sẽ bỏ qua khóa này. Các giá trị chính bị ảnh hưởng là:

  • isPrototypeOf
  • hasOwnProperty
  • toLocaleString
  • toString
  • valueOf

Để thực sự an toàn trong IE bạn phải sử dụng một cái gì đó như:

for (var key in myObject) {
  alert(key);
}

var shadowedKeys = [
  "isPrototypeOf",
  "hasOwnProperty",
  "toLocaleString",
  "toString",
  "valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
  if map.hasOwnProperty(a[i])) {
    alert(a[i]);
  }
}

Tin vui là EcmaScript 5 định nghĩa hàm Object.keys(myObject), trả về các khóa của một đối tượng dưới dạng mảng và một số trình duyệt (ví dụ: Safari 4) đã triển khai nó.

50
Fabian Jakobs

Trong các trình duyệt hiện đại (ECMAScript 5) để có được tất cả các thuộc tính bạn có thể làm:

Object.keys (obj) (Kiểm tra liên kết để có đoạn trích để tương thích ngược trên các trình duyệt cũ hơn)

Hoặc để có được các thuộc tính không thể đếm được:

Object.getOwnPropertyNames (obj)

Kiểm tra bảng tương thích ECMAScript 5

Thông tin bổ sung: Thuộc tính có thể đếm được là gì?

44
Carlos Ruana

Tôi nghĩ rằng một ví dụ về trường hợp khiến tôi ngạc nhiên là có liên quan:

var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
  document.writeln( propertyName + " : " + myObject[propertyName] );
}

Nhưng tôi ngạc nhiên, đầu ra là

name : Cody
status : Surprised
forEach : function (obj, callback) {
    for (prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
            callback(prop);
        }
    }
}

Tại sao? Một tập lệnh khác trên trang đã mở rộng nguyên mẫu Object:

Object.prototype.forEach = function (obj, callback) {
  for ( prop in obj ) {
    if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
      callback( prop );
    }
  }
};
24
cyberhobo
for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}
16
Andrew Hedges

Mã JavaScript đơn giản:

for(var propertyName in myObject) {
   // propertyName is what you want.
   // You can get the value like this: myObject[propertyName]
}

jQuery:

jQuery.each(obj, function(key, value) {
   // key is what you want.
   // The value is in: value
});
10
EmRa228

Tôi đã tìm thấy nó ... for (property in object) { // do stuff } sẽ liệt kê tất cả các thuộc tính, và do đó tất cả các biến được khai báo toàn cầu trên đối tượng cửa sổ ..

9
davenpcj

Đây là cách liệt kê các thuộc tính của đối tượng:

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}
8
Chtiwi Malek

Nếu bạn đang sử dụng thư viện nderscore.js , bạn có thể sử dụng hàm phím :

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
7
dkl

Dict của Python có phương thức 'key' và điều đó thực sự hữu ích. Tôi nghĩ trong JavaScript chúng ta có thể có một cái gì đó này:

function keys(){
    var k = [];
    for(var p in this) {
        if(this.hasOwnProperty(p))
            k.Push(p);
    }
    return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });

EDIT: Nhưng câu trả lời của @ carlos-ruana hoạt động rất tốt. Tôi đã thử nghiệm Object.keys (cửa sổ) và kết quả là những gì tôi mong đợi.

EDIT sau 5 năm: không nên mở rộng Object, vì nó có thể xung đột với các thư viện khác có thể muốn sử dụng keys trên các đối tượng của họ và nó sẽ dẫn đến hành vi không thể đoán trước trong dự án của bạn. @ carlos-ruana trả lời là cách chính xác để lấy chìa khóa của một đối tượng.

5
Fabio Montefuscolo

Bạn có thể sử dụng for của vòng lặp.

Nếu bạn muốn sử dụng một mảng:

Object.keys(object1)

Tham chiếu Object.keys ()

4
Walle Cyril

Nếu bạn đang cố gắng liệt kê các thuộc tính để viết mã mới chống lại đối tượng, tôi khuyên bạn nên sử dụng trình gỡ lỗi như Fireorms để xem chúng một cách trực quan.

Một kỹ thuật tiện dụng khác là sử dụng Object.toJSON () của Prototype để tuần tự hóa đối tượng thành JSON, nó sẽ hiển thị cho bạn cả tên và giá trị thuộc tính.

var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'

http://www.prototypejs.org/api/object/tojson

2
Chase Seibert

Tôi vẫn là người mới bắt đầu sử dụng JavaScript, nhưng tôi đã viết một hàm nhỏ để in đệ quy tất cả các thuộc tính của một đối tượng và các con của nó:

getDescription(object, tabs) {
  var str = "{\n";
  for (var x in object) {
      str += Array(tabs + 2).join("\t") + x + ": ";
      if (typeof object[x] === 'object' && object[x]) {
        str += this.getDescription(object[x], tabs + 1);
      } else {
        str += object[x];
      }
      str += "\n";
  }
  str += Array(tabs + 1).join("\t") + "}";
  return str;
}
0
Felix Lapalme