Lặp lại thông qua các thuộc tính đối tượng


2040

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(propt + ': ' + obj[propt]);
}

Làm thế nào để biến proptđại diện cho các thuộc tính của đối tượng? Đây không phải là một phương thức hoặc tài sản tích hợp. Tại sao nó đến với mọi tài sản trong đối tượng?


11
if (typeof(obj[propt]) === 'object') {/ * Làm lại * /}
noob

13
Vâng, thực sự xin lỗi cho câu hỏi này. Tôi biết vòng lặp là gì, tôi không thể hiểu được "vòng lặp thông qua các thuộc tính đối tượng", mà tôi nghĩ bây giờ đã bị xóa. Ngoài ra, họ đã giới thiệu cho tôi "JavaScript từng bước phiên bản 2 - Steve Suehring ở trường.
Rafay

242
Đây là một câu hỏi người mới bắt đầu tốt. Tôi nói thêm rằng tôi có 15 năm kinh nghiệm chuyên môn với các ngôn ngữ khác và tôi cần câu trả lời này. Tôi sẽ cộng thêm 2000 nếu có thể.
Nathan C. Tresch

60
Thật điên rồ, nhưng tôi đã đến trang này vài tháng một lần trong nhiều năm để học lại cú pháp về cách làm điều này. Tôi không nhớ làm thế nào để làm điều này ... Tôi chỉ nhớ rằng trang này luôn ở đây trên SO.
HDave

14
Đây là trang lạ nhất tôi từng thấy trên StackOverflow. Nếu bạn đọc kỹ câu hỏi, chỉ có một câu trả lời thậm chí bắt đầu cố gắng trả lời những gì thực sự được hỏi và nó có điểm -6. Câu trả lời cho điểm cao nhất, được chấp nhận, không chỉ không trả lời, mà đơn giản là sai.

Câu trả lời:


2426

Lặp lại các thuộc tính yêu cầu hasOwnPropertykiểm tra bổ sung này :

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

Điều đó là cần thiết bởi vì nguyên mẫu của một đối tượng chứa các thuộc tính bổ sung cho đối tượng là một phần kỹ thuật của đối tượng. Các thuộc tính bổ sung này được kế thừa từ lớp đối tượng cơ sở, nhưng vẫn là các thuộc tính của obj.

hasOwnProperty chỉ cần kiểm tra xem liệu đây có phải là một thuộc tính dành riêng cho lớp này không và không được thừa kế từ lớp cơ sở.


Cũng có thể gọi hasOwnPropertyqua chính đối tượng:

if (obj.hasOwnProperty(prop)) {
    // do stuff
}

Nhưng điều này sẽ thất bại nếu đối tượng có trường không liên quan có cùng tên:

var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo');  // TypeError: hasOwnProperty is not a function

Đó là lý do tại sao an toàn hơn để gọi nó qua Object.prototypethay thế:

var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo');  // true

21
@BT Theo tài liệu của Mozilla : "Nếu bạn chỉ muốn xem xét các thuộc tính được gắn vào chính đối tượng đó chứ không phải các nguyên mẫu của nó, hãy sử dụng getOwnPropertyNames hoặc thực hiện kiểm tra hasOwnProperty (propertyIsEnumerable cũng có thể được sử dụng)."
davidmdem

3
Chính xác thì điểm gọi là object.hasOwnProperty()gì? Không thực tế propertycó bất cứ giá trị nào ngụ ý rằng nó trong object?
Alex S

6
Bởi vì, Alex S, nguyên mẫu của một đối tượng chứa các thuộc tính bổ sung cho đối tượng là một phần kỹ thuật của đối tượng. Chúng được kế thừa từ lớp đối tượng cơ sở, nhưng chúng vẫn là các thuộc tính. hasOwnProperty chỉ cần kiểm tra xem đây có phải là thuộc tính dành riêng cho lớp này không và không được thừa kế từ lớp cơ sở. Một lời giải thích hay: brianflove.com/2013/09/05/javascripts-hasownproperty-method
Kyle Richter

87
Tôi cảm thấy rằng tôi nên đề cập, tuy nhiên, Object.keys (obj) bây giờ là một giải pháp tốt hơn nhiều để lấy các khóa của chính đối tượng. Liên kết đến tài liệu Mozilla: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

9
Một phần quan trọng của thông tin bị thiếu. propertylà một chuỗi ở đây, nên đã được gọi propertyName. Nếu không, có thể gây nhầm lẫn cho những người mới sử dụng JS như tôi, tức là phải làm gì bên trong if.
Neolisk

1136

Kể từ JavaScript 1.8.5, bạn có thể sử dụng Object.keys(obj)để lấy Mảng thuộc tính được xác định trên chính đối tượng (những thuộc tính trả về true obj.hasOwnProperty(key)).

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

Điều này tốt hơn (và dễ đọc hơn) so với sử dụng vòng lặp for-in.

Nó được hỗ trợ trên các trình duyệt này:

  • Firefox (Tắc kè): 4 (2.0)
  • Chrome: 5
  • Internet Explorer: 9

Xem tài liệu tham khảo của Mozilla Developer Network Object.keys () để biết thêm thông tin.


7
Điều này hiện được hỗ trợ rộng rãi hơn: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

3
Và nếu bạn cần hỗ trợ cho các trình duyệt cũ, bạn có thể sử dụng polyfill
KyleMit

27
Trong các môi trường hỗ trợ xây dựng ngôn ngữ này, phương thức này cho phép Array.foreach được gọi là:Object.keys(myObject).forEach(function(key,index) { //key = the name of the object key //index = the ordinal position of the key within the object });
Giá cả

4
@ AJ_83 Không có cách nào tốt để thoát ra khỏi forEach (). Sử dụng một số () trong trường hợp này và trả về giá trị true để phá vỡ
Daniel Z.

11
Tại sao điều này dễ đọc hơn for-in? for candidate in candidateStatus... dường như có thể đọc được với tôi
Jona

309

Các cô gái và các chàng trai chúng ta đang ở trong năm 2019 và chúng ta không có nhiều thời gian để gõ ... Vì vậy, hãy làm điều này ECMAScript 2016 thú vị mới này:

Object.keys(obj).forEach(e => console.log(`key=${e}  value=${obj[e]}`));

17
Làm thế nào điều này khác với câu trả lời của Danny R?
krillgar

27
Nó là một oneliner và sử dụng bản đồ thay vì forEach. Và cả satement console.log có thể thú vị đối với một số người.
Frank Roth

Satly, điều đó không hoạt động khi obj=window.performance.memory: - / Trường hợp như for invậy. tức làvar obj = window.performance.memory; for( key in obj ) console.log( 'key=' + key + ' val=' + obj[key] );
Michaelangel007

2
window.performance.memorychỉ được hỗ trợ bởi chrome và Object.keys(obj)trả về một mảng trống. Điều này không có gì để làm với .map.
Frank Roth

Trong trường hợp bất cứ ai không muốn khỉ xung quanh việc tái cấu trúc lớp lót đơn này để làm nhiều việc cùng một lúc e, tôi đã đăng ý chính này. Đó là cơ bản giống như hầu hết các trường băm, và sử dụng ( (key) => (value) )thay vì { key => value }, nhưng nếu bạn không có để đối phó với điều đó trước đây, nó có thể giúp bạn hình dung nó tốt hơn: gist.github.com/the-nose-knows/9f06e745a56ff20519707433e28a4fa8
kayleeFrye_onDeck

216

Đó là for...in statement(thông số MDN , ECMAScript ).

Bạn có thể đọc nó như là " CHO mỗi tài sản TRÊN các objđối tượng, chuyển nhượng mỗi tài sản cho PROPT biến lần lượt".


1
Cảm ơn rất nhiều, tôi hiểu nó bây giờ. Tôi đã đập đầu mình, lướt qua sách và Google.
Rafay

21
Đồng ý với @RightSaidFred, innhà điều hành và fortuyên bố hoàn toàn không liên quan, for-intuyên bố này tự thể hiện một sản phẩm ngữ pháp : for ( LeftHandSideExpression in Expression ),for ( var VariableDeclarationNoIn in Expression )
CMS

2
Câu trả lời kỳ lạ này có rất nhiều phiếu bầu, đặc biệt là vì những bình luận phổ biến này dường như mâu thuẫn với nó.
Doug Molineux

9
Tại sao điều này được đánh dấu là câu trả lời? Nó hoàn toàn có thể là thứ ít hữu ích nhất trong chủ đề này ..
computrius 12/12/13

3
Ít trả lời hữu ích? Phụ thuộc vào những gì bạn nghĩ rằng OP đã yêu cầu; Khi tôi lần đầu tiên đọc câu hỏi, nó có vẻ như bối rối về cơ chế mà một biến có thể được sử dụng để kiểm tra các thuộc tính của đối tượng và câu trả lời này giải thích một cách hùng hồn (cách hiểu sai 'không hiểu'). Câu hỏi "Tại sao nó xuất hiện với mọi tài sản" Tôi thấy có thể ám chỉ OP đang tìm kiếm hasOwnProperty nhưng không biết điều đó, nhưng tôi nghĩ nhiều khả năng đây là điều OP muốn biết và đã chấp nhận không chính xác trả lời cho một câu hỏi khác :-)
Bumpy

157

Trong các triển khai ES cập nhật, bạn có thể sử dụng Object.entries:

for (const [key, value] of Object.entries(obj)) { }

hoặc là

Object.entries(obj).forEach(([key, value]) => ...)

Nếu bạn chỉ muốn lặp lại các giá trị, thì hãy sử dụng Object.values:

for (const value of Object.values(obj)) { }

hoặc là

Object.values(obj).forEach(value => ...)

đây sẽ là giải pháp tốt nhất (object.entries ...), nhưng tôi không thể sử dụng nó. Khi bạn muốn làm điều này nhiều lần và không thể hỗ trợ nó trong khung của bạn, bạn có thể sử dụng polyfill trên trang này: developer.mozilla.org/nl/docs/Web/JavaScript/Reference/
Mario

Gợi ý thứ ba là tuyệt vời nếu bạn chỉ các giá trị của thuộc tính. Tuyệt vời!
Ginzburg


27

Nếu môi trường của bạn hỗ trợ ES2017 thì tôi sẽ khuyên dùng Object.entries :

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`);
});

Như thể hiện trong tài liệu Mozillas Object.entries () :

Phương thức Object.entries () trả về một mảng các cặp thuộc tính [khóa, giá trị] riêng của một đối tượng đã cho, theo cùng thứ tự được cung cấp bởi một vòng lặp for ... trong vòng lặp (sự khác biệt là một vòng lặp for tính chất trong chuỗi nguyên mẫu là tốt).

Về cơ bản với Object.entries, chúng ta có thể bỏ qua bước bổ sung sau được yêu cầu với vòng lặp cũ hơn cho ... trong vòng lặp:

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}

22

jquery cho phép bạn làm điều này ngay bây giờ:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});

1
$.each({foo:1, length:0, bar:2}, function(k,v){console.log(k,v)})$ .each không phù hợp với các đối tượng. Nếu một đối tượng tình cờ có thuộc tính độ dài và giá trị của nó bằng 0, toàn bộ đối tượng được xử lý như thể đó là một mảng trống.
Bob Stein

Chi tiết tại sao tôi nghĩ rằng đây là một cách tiếp cận mời lỗi .
Bob Stein

21

Câu trả lời của Dominik là hoàn hảo, tôi chỉ thích làm theo cách đó, vì nó dễ đọc hơn:

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}

Có nên Objectvới chữ hoa mặc dù, không?
Jonathan

18

Các câu trả lời ở trên hơi khó chịu vì chúng không giải thích những gì bạn làm trong vòng lặp for sau khi bạn đảm bảo đó là một đối tượng: BẠN KHÔNG TIẾP CẬN NÓ TRỰC TIẾP! Bạn thực sự chỉ được cung cấp KHÓA mà bạn cần áp dụng cho OBJ:

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

Đây là tất cả ECMA5 an toàn. Thậm chí hoạt động trong các phiên bản JS khập khiễng như Rhino;)


15

Để thêm cách sử dụng của ES2015 Reflect.ownKeys(obj)và cũng lặp lại các thuộc tính thông qua một trình vòng lặp.

Ví dụ:

let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };

có thể được lặp đi lặp lại bởi

// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));

Nếu bạn muốn lặp lại trực tiếp các giá trị của các khóa của một đối tượng, bạn có thể định nghĩa một iterator, giống như các trình lặp mặc định của JavaScipts cho các chuỗi, mảng, mảng được gõ, Map và Set.

JS sẽ cố gắng lặp lại thông qua thuộc tính iterator mặc định, phải được định nghĩa là Symbol.iterator.

Nếu bạn muốn có thể lặp lại trên tất cả các đối tượng, bạn có thể thêm nó làm nguyên mẫu của Object:

Object.prototype[Symbol.iterator] = function*() { 
    for(p of Reflect.ownKeys(this)){ yield this[p]; }
}

Điều này sẽ cho phép bạn lặp lại các giá trị của một đối tượng với ... vòng lặp, ví dụ:

for(val of obj) { console.log('Value is:' + val ) }

Thận trọng : Khi viết câu trả lời này (tháng 6 năm 2018) tất cả các trình duyệt khác, nhưng IE, hỗ trợ trình tạo và for...oflặp quaSymbol.iterator


Mặc dù bạn không thực sự trả lời câu hỏi của OP, nhưng điều này rất hữu ích cho tôi, tôi chưa biết về Reflect.
Michiel

15
if(Object.keys(obj).length) {
    Object.keys(obj).forEach(key => {
        console.log("\n" + key + ": " + obj[key]);
    });
}

// *** Explanation line by line ***

// Explaining the bellow line
// It checks if obj has at least one property. Here is how:
// Object.keys(obj) will return an array with all keys in obj
// If there is no keys in obj, it will return empty array = []
// Then it will get it's length, if it has at least one element,
// it's bigger than 0 which evaluates to true and the bellow 
// code will be executed.
// Else means it's length = 0 which evaluates to false
// NOTE: you can use Object.hasOwnProperty() instead of Object.keys(obj).length
if(Object.keys(obj).length) {

    // Explaining the bellow line
    // Just like in the previous line, this returns an array with
    // all keys in obj (because if code execution got here, it means 
    // obj has keys.) 
    // Then just invoke built-in javascript forEach() to loop
    // over each key in returned array and calls a call back function 
    // on each array element (key), using ES6 arrow function (=>)
    // Or you can just use a normal function ((key) { blah blah }).
    Object.keys(obj).forEach(key => {

        // The bellow line prints out all keys with their 
        // respective value in obj.
        // key comes from the returned array in Object.keys(obj)
        // obj[key] returns the value of key in obj
        console.log("\n" + key + ": " + obj[key]);
    });
}

3
Xin chào, bạn có thể thêm thông tin về câu trả lời của mình không, chỉ cung cấp mã không có ích.
Nicolas

Xin chào @Nicolas Tôi đã thêm một dòng giải thích theo dòng cho mã. Hãy cho tôi biết nếu nó vẫn chưa rõ ràng
Fouad Boukredine

Bởi vì forEach bỏ qua các giá trị trống , tôi nghĩ bạn có thể thoát khỏi nếu và chỉ cần làmObject.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`)); câu trả lời như câu trả lời của Frank Roth.
Sản phẩm tối

12

Vòng lặp for ... in đại diện cho mỗi thuộc tính trong một đối tượng vì nó giống như vòng lặp for. Bạn đã xác định propt trong vòng lặp for ... bằng cách thực hiện:

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

A cho ... trong vòng lặp lặp qua các thuộc tính vô số của một đối tượng. Bất kỳ biến nào bạn xác định hoặc đặt vào vòng lặp for ... trong vòng lặp, sẽ thay đổi mỗi lần nó chuyển sang thuộc tính tiếp theo mà nó lặp lại. Biến trong vòng lặp for ... lặp lại thông qua các khóa, nhưng giá trị của nó là giá trị của khóa. Ví dụ:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

Bạn có thể thấy biến khác với giá trị của biến như thế nào. Ngược lại, một ... cho vòng lặp làm ngược lại.

Tôi hi vọng cái này giúp được.


11
let obj = {"a": 3, "b": 2, "6": "a"}

Object.keys(obj).map((item) => {console.log("item", obj[item])})

// a
// 3
// 2

1
Như đã đề cập trong các bình luận khác, forEachở đây thích hợp hơn, vì mapdự định trả về một mảng mới với kết quả gọi khối mã trên mỗi lần lặp. Nhưng chúng tôi chỉ quan tâm đến các tác động phụ của mỗi lần lặp chứ không phải giá trị trả về, do đó chúng tôi không cần mảng mới mapmang lại cho chúng tôi.
Daniel


10

Bạn có thể sử dụng Lodash. Tài liệu

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});

10
Tại sao trên "trái đất" này có 10 câu trả lời? Nó hoàn toàn không trả lời câu hỏi. Tôi bắt đầu mất niềm tin vào trí thông minh của nhà phát triển JS trung bình.
nhà phát triển

1
@developerbmw Tôi hiểu rằng sử dụng các tính năng ES6 là cách đúng đắn hơn, nhưng tôi đã trả lời một năm trước. Xin vui lòng, chia sẻ suy nghĩ của bạn với chúng tôi khi bạn có một phút.
viktarpunko

1
Ý tưởng là tập trung nhiều hơn vào các phương thức gốc, thay vì đề nghị người dùng thêm thư viện 10000 dòng vào trang của họ. Đừng hiểu lầm tôi, tôi thích sử dụng Lodash nhưng có một thời gian và một nơi dành cho nó và nó không phải là cái này.

9

forVòng lặp của bạn đang lặp lại trên tất cả các thuộc tính của đối tượng obj. proptđược định nghĩa trong dòng đầu tiên của vòng lặp for của bạn. Nó là một chuỗi là tên của một thuộc tính của objđối tượng. Trong lần lặp đầu tiên của vòng lặp, proptsẽ là "tên".


9

Các đối tượng trong JavaScript là tập hợp các thuộc tính và do đó có thể được lặp trong một câu lệnh cho mỗi câu lệnh.

Bạn nên nghĩ về objmột bộ sưu tập giá trị quan trọng.


! với sự khác biệt quan trọng là các 'danh sách thuộc tính' này có thể có tên là khóa, trong khi mảng JS bình thường chỉ có thể có số làm khóa.
Qqwy

9

Ngày nay, bạn có thể chuyển đổi một đối tượng JS tiêu chuẩn thành một đối tượng có thể lặp lại chỉ bằng cách thêm một phương thức Symbol.iterator. Sau đó, bạn có thể sử dụng một for ofvòng lặp và nhận trực tiếp các giá trị của nó hoặc thậm chí có thể sử dụng toán tử trải trên đối tượng. Mát mẻ. Hãy xem cách chúng tôi có thể làm cho nó:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);


1
Cách thú vị để làm điều đó. Cảm ơn đã function*khám phá!
Đến

5

Nếu chạy Node, tôi khuyên bạn nên:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});

5

Mặc dù câu trả lời được xếp hạng cao nhất là chính xác, đây là trường hợp sử dụng thay thế, tức là nếu bạn đang lặp lại một đối tượng và muốn tạo một mảng cuối cùng. Sử dụng .mapthay vìforEach

const newObj = Object.keys(obj).map(el => {
    //ell will hold keys 
   // Getting the value of the keys should be as simple as obj[el]
})

4

Ngoài ra, thêm cách đệ quy:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

Sử dụng:

iterate({ foo: "foo", bar: { foo: "foo"} }); 

1
@faiz - xem ý kiến ​​của tôi, đó là biện pháp bảo vệ khỏi bị mắc kẹt trong vòng lặp vô tận khi bạn thường xuyên đi bộ qua máng có các tài liệu tham khảo theo chu kỳ
Ondrej Svejdar 22/2/2016

3

Vòng lặp for..in làm gì là nó tạo ra một biến mới (var someVariable) và sau đó lưu trữ từng thuộc tính của đối tượng đã cho trong biến mới này (someVariable) từng cái một. Do đó, nếu bạn sử dụng khối {}, bạn có thể lặp lại. Hãy xem xét ví dụ sau.

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet

Nâng cao điều này, vì nó đơn giản. Trong trường hợp sử dụng của tôi, tôi cần kiểm tra tất cả các thuộc tính trong một đối tượng để tìm các giá trị tinh ranh - NaN, null, không xác định (chúng là các điểm trên biểu đồ và các giá trị này ngăn không cho biểu đồ vẽ). Để có được giá trị thay vì tên, trong vòng lặp bạn sẽ làm obj[someVariable]. Có lẽ lý do nó bị hạ cấp rất nhiều là vì nó không được đệ quy. Vì vậy, đây sẽ không phải là một giải pháp thích hợp nếu bạn có một đối tượng có cấu trúc cao.
Katharine Ostern

@KatharineOstern hoặc có lẽ là do cụm từ sau đây hơi khó hiểu: "Do đó, nếu bạn sử dụng khối {}, bạn có thể lặp lại." Các mã nói nhiều hơn văn bản.
bvdb

3

Ở đây tôi đang lặp lại từng nút và tạo tên nút có ý nghĩa. Nếu bạn để ý, instanceOf Array và instanceOf Object thực hiện khá nhiều điều tương tự (trong ứng dụng của tôi, tôi đang đưa ra logic khác nhau)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

lưu ý - Tôi lấy cảm hứng từ câu trả lời của Ondrej Svejdar. Nhưng giải pháp này có hiệu suất tốt hơn và ít mơ hồ hơn


3

Về cơ bản, bạn muốn lặp qua từng thuộc tính trong đối tượng.

Câu đố

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

obj(prop)<- TypeError: obj không phải là một chức năng
le_m

@le_m xấu của tôi. Tôi phải vô tình lấy ra hasOwnPropertythuộc tính. Nó nên hoạt động ngay bây giờ.
HovyTech

2

Tôi muốn thêm vào các câu trả lời ở trên, vì bạn có thể có ý định khác với Javascript. Một đối tượng JSON và một đối tượng Javascript là những thứ khác nhau và bạn có thể muốn lặp lại thông qua các thuộc tính của đối tượng JSON bằng các giải pháp được đề xuất ở trên, sau đó sẽ ngạc nhiên.

Giả sử rằng bạn có một đối tượng JSON như:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

Cách sai để lặp qua 'thuộc tính' của nó:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

Bạn có thể ngạc nhiên khi thấy giao diện điều khiển khai thác gỗ 0, 1vv khi iterating thông qua các thuộc tính của prop1prop2và của prop3_1. Các đối tượng đó là các chuỗi và các chỉ mục của một chuỗi là các thuộc tính của đối tượng đó trong Javascript.

Một cách tốt hơn để lặp lại đệ quy thông qua các thuộc tính đối tượng JSON là trước tiên hãy kiểm tra xem đối tượng đó có phải là một chuỗi hay không:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}

1

Để tiếp tục tinh chỉnh câu trả lời được chấp nhận, điều đáng chú ý là nếu bạn khởi tạo đối tượng bằng một var object = Object.create(null)thì object.hasOwnProperty(property)sẽ kích hoạt TypeError. Vì vậy, để an toàn, bạn cần gọi nó từ nguyên mẫu như thế này:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}

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.