For..In vòng lặp trong JavaScript - cặp giá trị khóa


414

Tôi đã tự hỏi nếu có một cách để làm một cái gì đó như một foreachvòng lặp PHP trong JavaScript. Chức năng tôi đang tìm kiếm là một cái gì đó giống như đoạn trích PHP này:

foreach($data as $key => $value) { }

Tôi đã xem xét for..invòng lặp JS , nhưng dường như không có cách nào để chỉ định as. Nếu tôi làm điều này với một vòng lặp 'bình thường' cho vòng lặp ( for(var i = 0; i < data.length; i++), có cách nào để lấy các cặp khóa => giá trị không?

Câu trả lời:


216

Nếu bạn có thể sử dụng ES6 nguyên bản hoặc với Babel (trình biên dịch js) thì bạn có thể làm như sau:

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

for (const [key, value] of Object.entries(test)) {
  console.log(key, value);
}

Mà sẽ in ra đầu ra này:

a 1
b 2
c 3

Các Object.entries()phương thức trả về một mảng tài sản đếm được riêng một đối tượng nhất định của [key, value]cặp, theo thứ tự giống như được cung cấp bởi một for...invòng lặp (sự khác biệt là có một cho-in liệt kê vòng lặp tính trong chuỗi ban đầu cũng) .

Hy vọng nó giúp! =)


1
Điều này hoạt động hoàn hảo, chỉ cần tự hỏi - so với "cho khóa trong đối tượng và sau đó nhận giá trị theo đối tượng [khóa]", cái nào cho hiệu suất tốt hơn?
luy

1
Trong trường hợp cụ thể này, tôi sẽ cho rằng nó chậm hơn vì Object.entriescuộc gọi. Tôi đã không chạy bất kỳ thử nghiệm mặc dù.
Francesco Casula

6
đây là câu trả lời tốt nhất cho câu hỏi trong tay, câu hỏi về việc lấy cả khóa và giá trị trong vòng lặp for.
cipak

4
Câu trả lời được chấp nhận nên được cập nhật vì điều này thực sự trả lời câu hỏi, mặc dù nó không có sẵn tại thời điểm của câu hỏi.
Marc Qualie

1
Bạn có thể muốn kiểm tra câu hỏi này: stackoverflow.com/questions/47213651/ , điều này dường như chỉ ra rằng một cú pháp của loại này sẽ được đề xuất: Object.keys (myObject) .forEach (key => {...
Will59

519
for (var k in target){
    if (target.hasOwnProperty(k)) {
         alert("Key is " + k + ", value is " + target[k]);
    }
}

hasOwnPropertyđược sử dụng để kiểm tra xem bạn targetcó thực sự có tài sản đó hay không, thay vì thừa hưởng nó từ nguyên mẫu của nó. Đơn giản hơn một chút sẽ là:

for (var k in target){
    if (typeof target[k] !== 'function') {
         alert("Key is " + k + ", value is" + target[k]);
    }
}

Nó chỉ kiểm tra mà kkhông phải là một phương pháp (như thể targetarraybạn sẽ nhận được rất nhiều các phương pháp cảnh báo, ví dụ như indexOf, push, pop, vv.)


87
Một cách khác để chỉ lặp lại các thuộc tính "của riêng" là Object.keys. Object.keys(target).forEach(function (key) { target[key]; });.
katspaugh

3
sẽ không hoạt động nếu targetđược tạo bằng cách sử dụng Object.create(null), mã sẽ được thay đổi target.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder

Tại sao không sử dụng các biến được đưa ra trong ví dụ câu hỏi? Đây là gì k, targetproperty? Đối với tôi, không phải là javascripter khu vực này không xác định :)
Gediminas

2
Object.keys (đích) .forEach ((key) => {target [key];}); cho Angular
Askilondz

315

Không ai đề cập đến Object.keysnên tôi sẽ đề cập đến nó.

Object.keys(obj).forEach(function (key) {
   // do something with obj[key]
});

3
Lưu ý: Không được hỗ trợ bởi IE8 trở xuống.
Edwin Stoteler

1
Tại thời điểm này, bạn nên sử dụng shim ES5. Nếu bạn đang sống trong tương lai ES6 tốt đẹp, hãy sử dụng for of tc39wiki.calculist.org/es6/for-of
dê dê

17
Điều đáng chú ý là "Không có cách nào để ngăn chặn hoặc phá vỡ vòng lặp forEach () ngoài việc ném một ngoại lệ"
rluks

Object.keys (obj) .forEach ((khóa) => {}); cho Angular
Askilondz

Nó không hoạt động trên ES6 hoặc tôi không hiểu nó. Felix có câu trả lời tốt hơn và dễ đọc hơn dưới đây: data.forEach (function (value, index) {console.log (index); // 0, 1, 2 ...});
gtamborero

115

cho ... trong sẽ làm việc cho bạn.

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

Trong JavaScript hiện đại, bạn cũng có thể làm điều này:

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

}

64
var obj = {...};
for (var key in obj) {
    var value = obj[key];

}

Cú pháp php chỉ là đường.


Điều này cũng sẽ lặp đi lặp lại trên tất cả các thuộc tính được kế thừa. Để tránh điều này, hãy sử dụng .hasOwnProperty ().
LSerni

24

Tôi giả sử bạn biết đó ilà chìa khóa và bạn có thể nhận được giá trị thông qua data[i](và chỉ muốn một phím tắt cho việc này).

ECMAScript5 đã giới thiệu forEach [MDN] cho các mảng (có vẻ như bạn có một mảng):

data.forEach(function(value, index) {

});

Tài liệu MDN cung cấp một shim cho các trình duyệt không hỗ trợ nó.

Tất nhiên điều này không hoạt động cho các đối tượng, nhưng bạn có thể tạo một chức năng tương tự cho chúng:

function forEach(object, callback) {
    for(var prop in object) {
        if(object.hasOwnProperty(prop)) {
            callback(prop, object[prop]);
        }
    }
}

Vì bạn đã gắn thẻ câu hỏi với , jQuery cung cấp $.each [docs] vòng lặp trên cả cấu trúc mảng và đối tượng.


Đó là Array forEach, không phải đối tượng forEach.

2
Vì thế? Rõ ràng OP đang lặp trên một mảng.
Felix Kling

Ngoài ra Mozilla (Firefox, SpiderMonkey-C, Rhino & c) có phần mở rộng không chuẩn cho phép for eachcú pháp. for each (let val in myObj) console.log(val);.
katspaugh

2
@katspaugh: Đúng vậy, nhưng chỉ là Mozilla, nó dường như không hữu ích lắm.
Felix Kling

Cảm ơn rất nhiều cho câu trả lời của bạn. Tôi sẽ đọc qua thông tin bạn cung cấp. Giả định của bạn khi bắt đầu câu trả lời là đúng, tôi biết rằng, ngoại trừ tôi có quá nhiều thứ trong đầu với dự án này đến nỗi tôi không thể tập trung và quên nó .. Cảm ơn bạn.
quán rượu


9
for (var key in myMap) {
    if (myMap.hasOwnProperty(key)) {
        console.log("key =" + key);
        console.log("value =" + myMap[key]);
    }
}

Trong javascript, mọi đối tượng đều có một cặp các cặp khóa-giá trị tích hợp có thông tin meta. Khi bạn lặp qua tất cả các cặp khóa-giá trị cho một đối tượng bạn cũng sẽ lặp qua chúng. Việc sử dụng hasOwnProperty () lọc các bộ lọc này ra.


2

ES6 sẽ cung cấp Map.prototype.forEach (gọi lại) có thể được sử dụng như thế này

myMap.forEach(function(value, key, myMap) {
                        // Do something
                    });

2
thông số này myMapđể làm gì?
phil294

Một bản đồ không phải là một đối tượng. Chúng là những thứ hoàn toàn riêng biệt.
Dakusan

2
Hàm forEach không chứa 'khóa' của mảng mà chỉ mục của phần tử mà bạn hiện đang lặp lại.
Francis Malloch

2
let test = {a: 1, b: 2, c: 3};
Object.entries(test).forEach(([key, value]) => console.log(key, value))

// a 1
// b 2
// c 3

5
Bạn có thể thêm một số giải thích với mã bạn đã đăng thay vì đăng một mã đơn giản có thể không hiểu được.
AaoIi

Object.entries lấy ra một mảng các mảng dựa trên các cặp khóa / giá trị của đối tượng ban đầu : [['a', 1],['b',2],['c',3]]. Việc forEachgiải cấu trúc từng mảng khóa / giá trị và đặt hai biến thành keyvalue, được sử dụng như bạn muốn hàm in - ở đây xuất ra console.log.
Mark Swardstrom

1

Bạn có thể sử dụng vòng lặp 'for in' cho việc này:

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


1

Nếu bạn đang sử dụng Lodash , bạn có thể sử dụng_.forEach

_.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
  console.log(key + ": " + value);
});
// => Logs 'a: 1' then 'b: 2' (iteration order is not guaranteed).

1

Trong vài năm qua kể từ khi câu hỏi này được đưa ra, Javascript đã thêm một vài tính năng mới. Một trong số đó là phương thức Object.Entries .

Sao chép trực tiếp từ MDN là đoạn mã sau


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

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

-2

vâng, bạn có thể có các mảng kết hợp trong javascript:

var obj = 
{
    name:'some name',
    otherProperty:'prop value',
    date: new Date()
};
for(i in obj)
{
    var propVal = obj[i]; // i is the key, and obj[i] is the value ...
}

@PaulPRO ... mọi thứ trong javascript là một cặp khóa-giá trị (do đó, một đối tượng trên thực tế là một mảng kết hợp của các cặp khóa-giá trị ...)
Alex Pacurar

@AlexPacurar và mảng kết hợp có một thứ tự. Một đối tượng là không có thứ tự. đó là một sự khác biệt lớn
Raynos

@Raynos bạn có thể đúng ... sẽ rất hữu ích để giải thích chính xác làm thế nào một đối tượng không được sắp xếp ... đưa ra ví dụ trên, người ta sẽ mong đợi rằng 'i' trong vòng lặp for là [name, otherProperty, và cuối cùng là ngày] ... vậy trong trường hợp nào thứ tự các thuộc tính của một đối tượng sẽ được trộn lẫn?
Alex Pacurar

@AlexPacurar thứ tự cụ thể mà nó sẽ lặp trên đối tượng là trình duyệt cụ thể. Một số làm theo thứ tự abc, một số làm theo thứ tự định nghĩa, v.v.
Raynos

3
@Raynos: Các mảng kết hợp có nhất thiết phải đặt hàng không? Tôi thường thấy thuật ngữ được sử dụng phổ biến hơn. Ví dụ, trên bài viết Wikipedia mảng kết hợp .
Jeremy Banks

-8
var global = (function() {
   return this;
})();

// Pair object, similar to Python

function Pair(key, value) {
    this.key = key;
    this.value = value;

    this.toString = function() {
       return "(" + key + ", " + value + ")";
    };
}

/**
 * as function
 * @param {String} dataName A String holding the name of your pairs list.
 * @return {Array:Pair} The data list filled
 *    with all pair objects.
 */
Object.prototype.as = function(dataName) {
    var value, key, data;
    global[dataName] = data = [];

    for (key in this) {
       if (this.hasOwnProperty(key)) {
          value = this[key];

          (function() {
             var k = key,
                 v = value;

            data.push(new Pair(k, v));
          })();
       }
    }

    return data;
};

var d = {
   'one': 1,
   'two': 2
};

// Loop on your (key, list) pairs in this way
for (var i = 0, max = d.as("data").length; i < max; i += 1) {
   key = data[i].key;
   value = data[i].value;

   console.log("key: " + key + ", value: " + value);
}

// delete data when u've finished with it.
delete data;
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.