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


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

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

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


1520
2017-11-29 14:30


gốc


if (typeof(obj[propt]) === 'object') {/* Làm lại lần nữa */ } - noob
Vâng, thực sự xin lỗi cho câu hỏi này. Tôi biết một vòng lặp là gì, tôi không thể có được đầu của tôi xung quanh "looping thông qua các thuộc tính đối tượng", mà tôi nghĩ là xóa bây giờ. Ngoài ra, họ đã đề nghị tôi "JavaScript từng bước 2 bản - Steve Suehring ở trường. - Rafay
Đây là một câu hỏi ăn xin tốt. Tôi muốn 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 2000 nếu tôi có thể. - Nathan C. Tresch
Crazy, 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ỉ cần nhớ rằng trang này luôn ở đây trên SO. - HDave
Đây là trang lạ nhất mà tôi đã 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ì đang thực sự được hỏi, và nó có số điểm là -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ác câu trả lời:


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

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}

Nó là cần thiết 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 mà là một phần kỹ thuật của đối tượng. Các thuộc tính bổ sung này được thừa hưởng từ lớp đối tượng cơ sở, nhưng vẫn là các thuộc tính của object.

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


2055
2018-05-24 12:38



@B T 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ới chính đối tượng đó chứ không phải 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
Chính xác thì điểm gọi là gì object.hasOwnProperty()? Không thực tế là property có bất kỳ giá trị nào ngụ ý rằng object? - Alex S
Bởi vì, Alex S, một nguyên mẫu của đối tượng chứa các thuộc tính bổ sung cho đối tượng mà là một phần kỹ thuật của đối tượng. Chúng được thừa hưởng 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 cụ thể cho lớp này hay không, và không phải là thuộc tính được thừa kế từ lớp cơ sở. Một lời giải thích tốt: brianflove.com/2013/09/05/javascripts-hasownproperty-method - Kyle Richter
Tôi cảm thấy rằng tôi nên đề cập đến, tuy nhiên, rằng Object.keys (obj) bây giờ là một giải pháp tốt hơn nhiều để nhận được các phím của đối tượng chính nó. Liên kết tới tài liệu của Mozilla: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Kyle Richter
Một phần thông tin quan trọng bị thiếu. property là một chuỗi ở đây, nên đã được gọi là propertyName. Nếu không, có thể gây nhầm lẫn cho người mới sử dụng JS như tôi, tức là phải làm gì bên trong if. - Neolisk


Kể từ JavaScript 1.8.5 bạn có thể sử dụng Object.keys(obj) để có được một mảng các thuộc tính được định nghĩa trên chính đối tượng đó (các đối tượng trả về true cho 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.

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

  • Firefox (Gecko): 4 (2.0)
  • Chrome: 5
  • Internet Explorer: 9

Xem Mạng nhà phát triển Mozilla Object.keys ()tham khảo để biết thêm thông tin.


775
2017-08-13 07:19



Điều này hiện được hỗ trợ rộng rãi hơn: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Dom Vinyard
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
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 }); - Todd Price
Giải pháp tốt. Nhưng làm thế nào để phá vỡ sự lặp lại?! - AJ_83
@ 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ề true để ngắt - Daniel Ziegler


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

Bạn có thể đọc nó dưới dạng "CHO mọi tài sản TRONG các obj đối tượng, gán từng thuộc tính cho PROPT thay đổi lần lượt ".


190
2017-11-29 14:32



Đồng ý với @RightSaidFred, in toán tử và for tuyên bố không liên quan gì cả, for-in tuyên bố đại diện cho sản xuất ngữ pháp một mình: for ( LeftHandSideExpression in Expression ), for ( var VariableDeclarationNoIn in Expression ) - CMS
Odd câu trả lời này có rất nhiều phiếu bầu, đặc biệt là vì những nhận xét phổ biến này dường như mâu thuẫn với nó. - Doug Molineux
Tại sao điều này được đánh dấu là câu trả lời? Nó là khá có thể là một trong những hữu ích nhất trong thread này .. - computrius
@PeteHerbertPenito, kỳ quặc rằng không ai làm phiền để chỉnh sửa câu trả lời cho đến tôi đã làm. - Dan Dascalescu
Câu trả lời hữu ích nhất? 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ư có vẻ bối rối về cơ chế mà theo đó 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à điều này câu trả lời giải thích hùng hồn (mặc dù không đúng nghĩa là 'mặc định'). 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ể ngụ ý OP đang tìm hasOwnProperty nhưng không biết, nhưng tôi nghĩ nó có nhiều khả năng hơn điều này là những gì OP muốn biết và đã chấp nhận sai câu trả lời chính xác cho một câu hỏi khác. :-) - Bumpy


Các cô gái và các chàng trai chúng tôi đang ở trong năm 2017 và chúng tôi không có nhiều thời gian để nhập ... Vì vậy, hãy làm điều này mới lạ ECMAScript ưa thích 2016:

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

144
2017-11-22 08:47



Điều này khác gì so với câu trả lời của Danny R? - krillgar
Nó là một oneliner và sử dụng bản đồ thay vì forEach. Và cũng có thể là sự an toàn của console.log đối với một số người. - Frank Roth
Nếu bạn không trực tiếp sao chép đoạn mã này và tự hỏi tại sao thông điệp nhật ký bảng điều khiển của bạn đang được coi là chuỗi, đừng quên sử dụng dấu gạch chéo (`) thay vì dấu nháy đơn (') xD - kayleeFrye_onDeck
Nếu bạn muốn lưu thêm 2 ký tự, bạn có thể loại bỏ () xung quanh e tranh luận... Object.keys(obj).map(e => console.log(`key=${e} value=${obj[e]}`)) - Grant
forEach phù hợp hơn ở đây. map() phù hợp hơn khi bạn muốn chuyển đổi dữ liệu và sử dụng giá trị được trả về bởi map(). Khi bạn đang sử dụng forEach bạn rõ ràng rằng bạn chỉ đang lặp cho các hiệu ứng phụ chứ không phải để chuyển đổi. - Ski


Trong các phiên bản sắp tới của ES, 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 qua các giá trị, hãy sử dụng Object.values:

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

hoặc là

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

58
2017-09-13 06:41



đâ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 thực hiện việc này nhiều lần và không thể hỗ trợ nó trong khung công tác của mình, bạn có thể sử dụng polyfill trên trang này: developer.mozilla.org/nl/docs/Web/JavaScript/Reference/… - Mario
Đề xuất thứ ba là tuyệt vời nếu bạn chỉ có các giá trị của thuộc tính. Tuyệt vời! - gnzg


Nó chỉ là một for...in vòng lặp. Kiểm tra tài liệu tại Mozilla.


37
2017-11-29 14:33



đó là một sự khác biệt khá cơ bản, không phải trong và xứng đáng xứng đáng với công đức bạn đã chỉ định. Đây là một câu trả lời kém bằng văn bản thiếu ngữ cảnh và ứng dụng cho câu hỏi ban đầu. - FlavorScape
Câu trả lời này vẫn tốt hơn nhiều so với hầu hết các câu trả lời hoàn toàn không giải quyết được câu hỏi. - developerbmw


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

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

20
2018-03-29 15:19



$.each({foo:1, length:0, bar:2}, function(k,v){console.log(k,v)}) $ .each là không phù hợp cho các đối tượng. Nếu một đối tượng xảy ra có một thuộc tính length và giá trị của nó xảy ra bằng không, toàn bộ đối tượng được xử lý như thể nó là một mảng rỗng. - Bob Stein
Chi tiết tại sao tôi nghĩ đây là phương pháp tiếp cận lỗi. - Bob Stein


Các câu trả lời ở trên là một chút khó chịu vì họ không giải thích những gì bạn làm bên trong vòng lặp cho sau khi bạn đảm bảo nó là một đối tượng: BẠN KHÔNG TRUY CẬP CNTT TRỰC TIẾP! Bạn thực sự chỉ gửi KEY 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í làm việc trong các phiên bản JS lame như Rhino;)


12
2017-10-28 05:39





Dominik's câu trả lời là hoàn hảo, tôi chỉ thích làm theo cách đó, vì nó sạch hơn để đọc:

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

    // Do stuff...
}

12
2018-01-19 11:03





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) {
    ...
});

11
2017-11-04 16:51



Tại sao trên trái đất này "câu trả lời" có 10 upvotes? Nó hoàn toàn không trả lời được câu hỏi. Tôi bắt đầu mất niềm tin vào trí thông minh về nhà phát triển JS trung bình. - developerbmw
Tôi hiểu rằng việc sử dụng các tính năng ES6 là đúng cách hơn, nhưng tôi đã trả lời cách đây một năm. Hãy chia sẻ suy nghĩ của bạn với chúng tôi khi bạn có một phút. - viktarpunko
Ý tưởng là tập trung hơn vào các phương thức gốc, thay vì đề xuất người dùng thêm thư viện dòng 10000 vào trang của họ. Đừng làm cho tôi sai, tôi thích sử dụng Lodash nhưng có một thời gian và một nơi cho nó và nó không phải là điều này. - Will Hoskings


Vòng lặp for ... đại diện cho mỗi thuộc tính trong một đối tượng vì nó giống như một vòng lặp for. Bạn định nghĩa propt trong for ... trong vòng lặp 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 đếm được của một đối tượng. Bất kỳ biến nào bạn xác định, hoặc đặt trong vòng lặp for ..., thay đổi mỗi khi nó đi đến thuộc tính tiếp theo 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. Ngược lại, một vòng lặp ... của vòng lặp ngược lại.

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


10
2018-01-24 03:57