สำหรับ .. ในลูปใน JavaScript - คู่ของค่าคีย์


414

ฉันสงสัยว่ามีวิธีการทำบางอย่างเช่นการforeachวนรอบPHP ใน JavaScript หรือไม่ ฟังก์ชั่นที่ฉันกำลังมองหาคืออะไรอย่าง PHP Snippet นี้:

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

ผมกำลังมองไปที่ JS for..inห่วง asแต่ดูเหมือนว่าจะมีวิธีการที่จะระบุไม่มี หากฉันทำสิ่งนี้ด้วย 'ปกติ' สำหรับลูป ( for(var i = 0; i < data.length; i++) มีวิธีในการจับคู่คีย์ => ค่าหรือไม่

คำตอบ:


215

หากคุณสามารถใช้ES6หรือด้วยBabel (js compiler) คุณสามารถทำสิ่งต่อไปนี้:

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

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

ซึ่งจะพิมพ์ผลลัพธ์นี้:

a 1
b 2
c 3

Object.entries()วิธีการส่งกลับอาร์เรย์ของวัตถุที่ได้รับของตัวเองคุณสมบัตินับ[key, value]คู่ในลำดับเช่นเดียวกับที่ให้บริการโดยfor...inวง(ความแตกต่างที่ว่าสำหรับในห่วงระบุคุณสมบัติในห่วงโซ่ต้นแบบเช่นกัน)

หวังว่ามันจะช่วย! =)


1
สิ่งนี้ใช้งานได้อย่างสมบูรณ์แบบเพียงแค่สงสัย - เมื่อเทียบกับ "สำหรับคีย์ในวัตถุแล้วรับค่าโดยวัตถุ [คีย์]" ซึ่งอันไหนให้ประสิทธิภาพดีกว่า
lsheng

1
ในกรณีเฉพาะนี้ฉันจะถือว่าช้ากว่าเพราะมีการObject.entriesโทร ฉันไม่ได้ทำการทดสอบใด ๆ
Francesco Casula

6
นี่เป็นคำตอบที่ดีที่สุดสำหรับคำถามในมือซึ่งถามเกี่ยวกับการคว้าทั้งคีย์และค่าในลูป for
cipak

4
คำตอบที่ยอมรับควรได้รับการอัปเดตเนื่องจากนี่เป็นคำตอบที่แท้จริงแม้ว่าจะไม่สามารถใช้ได้ในช่วงเวลาของคำถาม
Marc Qualie

1
คุณอาจต้องการตรวจสอบคำถามนี้: stackoverflow.com/questions/47213651/ซึ่งดูเหมือนว่าจะแนะนำว่าควรใช้ไวยากรณ์ประเภทนี้: 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ใช้เพื่อตรวจสอบว่าของคุณtargetมีคุณสมบัตินั้นจริง ๆ หรือไม่แทนที่จะสืบทอดมาจากต้นแบบ ง่ายกว่าเล็กน้อย:

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

มันเป็นเพียงแค่การตรวจสอบที่kไม่ได้เป็นวิธีการ (เช่นถ้าtargetเป็นarrayคุณจะได้รับจำนวนมากของวิธีการรับการแจ้งเตือนเช่นindexOf, push, popฯลฯ .)


87
อีกวิธีหนึ่งที่จะย้ำแค่คุณสมบัติ "ตัวเอง" Object.keysคือ Object.keys(target).forEach(function (key) { target[key]; });.
katspaugh

3
จะไม่ทำงานหากtargetถูกสร้างขึ้นโดยใช้Object.create(null)รหัสควรมีการเปลี่ยนแปลงtarget.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder

ทำไมไม่ใช้ตัวแปรที่กำหนดในตัวอย่างคำถาม? อะไรที่นี่คือk, targetและproperty? สำหรับฉันไม่ใช่ javascripter พื้นที่นี้ไม่ได้กำหนด :)
Gediminas

2
Object.keys (เป้าหมาย) .forEach ((key) => {target [key];}}; สำหรับ Angular
askilondz

315

ไม่มีใครพูดถึงObject.keysดังนั้นฉันจะพูดถึงมัน

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

3
หมายเหตุ: IE8 ไม่รองรับและด้านล่าง
Edwin Stoteler

1
ณ จุดนี้คุณควรใช้ ES5 shim หากคุณอาศัยอยู่ใน ES6 ที่ดีในอนาคตให้ใช้for of tc39wiki.calculist.org/es6/for-of
goatslacker

17
เป็นที่น่าสังเกตว่า "ไม่มีทางที่จะหยุดหรือทำลาย forEach () วงอื่นนอกจากการโยนข้อยกเว้น"
rluks

Object.keys (obj) .forEach ((key) => {}); สำหรับ Angular
askilondz

มันใช้งานไม่ได้กับ ES6 หรือฉันไม่เข้าใจ เฟลิกซ์มีคำตอบที่ดีกว่าและอ่านได้ง่ายกว่าด้านล่าง: data.forEach (ฟังก์ชัน (ค่า, ดัชนี) {console.log (ดัชนี); // 0, 1, 2 ... });
gtamborero


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

}

ไวยากรณ์ php เป็นเพียงน้ำตาล


สิ่งนี้จะทำซ้ำในคุณสมบัติที่สืบทอดทั้งหมด เพื่อหลีกเลี่ยงปัญหานี้ให้ใช้. hasOwnProperty ()
LSerni

24

ฉันถือว่าคุณรู้ว่าiเป็นกุญแจสำคัญและคุณสามารถรับค่าผ่านทางdata[i](และเพียงแค่ต้องการทางลัดสำหรับสิ่งนี้)

ECMAScript5 แนะนำforEach [MDN]สำหรับอาร์เรย์ (ดูเหมือนว่าคุณมีอาร์เรย์):

data.forEach(function(value, index) {

});

เอกสารประกอบ MDN จัดทำ shim สำหรับเบราว์เซอร์ที่ไม่รองรับ

แน่นอนว่านี่ใช้ไม่ได้กับวัตถุ แต่คุณสามารถสร้างฟังก์ชั่นที่คล้ายกันได้

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

เนื่องจากคุณติดแท็กคำถามด้วย , jQuery จัดเตรียม$.each [docs]ซึ่งวนรอบทั้งโครงสร้างอาร์เรย์และวัตถุ


นั่นเป็นอาร์เรย์ไม่วัตถุforEach forEach

2
ดังนั้น? เห็นได้ชัดว่า OP กำลังวนลูปมากกว่าอาเรย์
เฟลิกซ์คลิง

Mozilla (Firefox, SpiderMonkey-C, Rhino & c) ยังมีส่วนขยายที่ไม่ได้มาตรฐานซึ่งอนุญาตให้for eachใช้ไวยากรณ์ for each (let val in myObj) console.log(val);.
katspaugh

2
@katspaugh: ใช่ แต่เนื่องจากเป็น Mozilla เท่านั้นดูเหมือนจะไม่ได้มีประโยชน์มาก
เฟลิกซ์คลิง

ขอบคุณมากสำหรับคำตอบของคุณ ฉันจะอ่านข้อมูลที่คุณให้ไว้ ข้อสันนิษฐานของคุณในตอนต้นของคำตอบนั้นถูกต้องฉันรู้ว่ายกเว้นฉันได้รับมากในหัวของฉันกับโครงการนี้ที่ฉันไม่สามารถมุ่งเน้นและลืมเกี่ยวกับมัน .. ขอบคุณ
คาบาเร่ต์


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

ใน javascript วัตถุทุกชิ้นมีคู่ของคีย์ - ค่าในตัวที่มีข้อมูลเมตา เมื่อคุณวนลูปผ่านคู่คีย์ - ค่าทั้งหมดสำหรับวัตถุที่คุณกำลังลูปมัน การใช้ hasOwnProperty () จะกรองเหล่านี้ออก


2

ES6 จะให้ Map.prototype.forEach (การโทรกลับ) ซึ่งสามารถใช้งานได้เช่นนี้

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

2
พารามิเตอร์myMapคืออะไร
phil294

แผนที่ไม่ใช่วัตถุ มันเป็นสิ่งที่แยกจากกันอย่างสมบูรณ์
Dakusan

2
ฟังก์ชัน forEach ไม่มี 'key' ของ array แต่ยิ่งดัชนีขององค์ประกอบที่คุณกำลังทำซ้ำอยู่ในขณะนี้
ฟรานซิส 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
คุณอาจเพิ่มคำอธิบายด้วยรหัสที่คุณโพสต์แทนการโพสต์รหัสธรรมดาซึ่งอาจไม่เข้าใจ
AaoIi

ดึงออก Object.entries อาร์เรย์ของอาร์เรย์ขึ้นอยู่กับคีย์ / [['a', 1],['b',2],['c',3]]คู่มูลค่าของวัตถุต้นฉบับ: forEachชำแหละแต่ละคีย์ / อาร์เรย์คุ้มค่าและการตั้งค่าตัวแปรทั้งสองไปkeyและvalueจะใช้ตามที่คุณต้องการในการทำงาน - console.logที่นี่ในการส่งออก
Mark Swardstrom



1

หากคุณใช้Lodashคุณสามารถใช้_.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

ในช่วงไม่กี่ปีที่ผ่านมานับตั้งแต่มีการตั้งคำถามจาวาสคริปต์ได้เพิ่มคุณสมบัติใหม่บางอย่าง หนึ่งในนั้นคือวิธีการObject.Entries

คัดลอกโดยตรงจาก MDN คือข้อมูลโค้ดติดตาม


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

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

-2

ใช่คุณสามารถมีอาร์เรย์ที่เชื่อมโยงได้ใน 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 ... ทุกอย่างใน javascript เป็นคู่ของคีย์ - ค่า (ดังนั้นวัตถุจึงเป็นอาร์เรย์เชื่อมโยงของคู่ของคีย์ - ค่า ... )
Alex Pacurar

@AlexPacurar และอาร์เรย์ assocative มีคำสั่งซื้อ วัตถุไม่มีการจัดลำดับ thatsความแตกต่างใหญ่
Raynos

@ Raynos คุณอาจพูดถูก ... มันจะช่วยได้มากในการอธิบายว่าวัตถุไม่มีการเรียงลำดับอย่างไร ... จากตัวอย่างข้างต้นใคร ๆ ก็คาดหวังว่า 'i' ใน for for loop จะเป็น [name, otherProperty, และในที่สุดก็วันที่] ... ดังนั้นในสถานการณ์ใดลำดับของคุณสมบัติของวัตถุจะถูกผสม?
Alex Pacurar

@AlexPacurar ลำดับเฉพาะที่มันจะวนซ้ำวัตถุเป็นเบราว์เซอร์ที่เฉพาะเจาะจง บางคนทำตามลำดับตัวอักษรบางคนทำตามคำนิยาม ฯลฯ
Raynos

3
@ Raynos: จำเป็นต้องมีอาร์เรย์ที่เชื่อมโยงหรือไม่ ฉันมักจะเห็นคำที่ใช้โดยทั่วไปมากกว่า ตัวอย่างเช่นในบทความ Wikipedia ของอาเรย์
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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.