วนซ้ำอาร์เรย์ใน JavaScript


3144

ใน Java คุณสามารถใช้การforวนลูปเพื่อสำรวจวัตถุในอาร์เรย์ดังนี้

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

คุณสามารถทำเช่นเดียวกันใน JavaScript?


5
ตกลงดังนั้นฉันสับสนเล็กน้อยก็โอเคที่จะใช้การปรับปรุงสำหรับการวนซ้ำเมื่อคุณกำลังเข้าถึงวัตถุ? และใช้ลำดับหนึ่งสำหรับการเติม ถูกต้องหรือไม่
มาร์ค Szymanski

45
ไม่มันเป็นเรื่องง่ายมากที่วัตถุอาเรย์มีดัชนีเป็นตัวเลขดังนั้นคุณต้องการวนซ้ำดัชนีเหล่านั้นในลำดับตัวเลขลูปลำดับช่วยให้แน่ใจว่าลูปที่ปรับปรุงแล้ว for-inจะระบุคุณสมบัติของวัตถุโดยไม่ต้องมีคำสั่งเฉพาะและยังระบุคุณสมบัติที่สืบทอด .. สำหรับการวนซ้ำวนซ้ำในลำดับอาร์เรย์ขอแนะนำเสมอ ...
CMS

2
เกี่ยวข้อง - stackoverflow.com/questions/5349425/…
jondavidjohn

6
jsben.ch/#/Q9oD5 <= นี่คือมาตรฐานของเครือข่ายสำหรับการวนลูปผ่านอาร์เรย์
EscapeNetscape

3
@CMS ไม่มันไม่ง่ายเลย มันง่ายมากในทุก ๆ ภาษา มันซับซ้อนอย่างน่าขันใน JS ที่คุณมีinและofสามารถใช้และทำสิ่งต่าง ๆ ได้ จากนั้นคุณยังมีforEachและการวนลูปดัชนีที่น่าเกลียดและน่ารำคาญ ภาษาสมัยใหม่อื่น ๆ ทุกภาษาทำให้การรวบรวมเป็นเรื่องง่ายและตรงไปตรงมาโดยไม่ทำให้ประหลาดใจหรือสับสน JS ทำได้เช่นกัน แต่ก็ไม่เป็นเช่นนั้น
jpmc26

คำตอบ:


3958

คุณมีหลายทางเลือก:

1. วนตามลำดับfor:

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

ข้อดี

  • ใช้ได้กับทุกสภาพแวดล้อม
  • คุณสามารถใช้breakและcontinueงบควบคุมการไหล

จุดด้อย

  • verbose เกินไป
  • ความจำเป็น
  • ง่ายต่อการมีข้อผิดพลาดแบบ off-one (บางครั้งเรียกว่าข้อผิดพลาดการโพสต์รั้ว )

2. Array.prototype.forEach

ข้อมูลจำเพาะ ES5 นำเสนอวิธีการอาเรย์ที่มีประโยชน์มากมายซึ่งหนึ่งในนั้นArray.prototype.forEachและมันทำให้เรามีวิธีที่กระชับในการวนซ้ำอาเรย์:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

เมื่อเกือบสิบปีที่ผ่านมาขณะที่เขียนข้อกำหนด ES5 ออกมา (ธันวาคม 2009) ได้มีการใช้งานโดยเอ็นจิ้นที่ทันสมัยเกือบทั้งหมดในเดสก์ท็อปเซิร์ฟเวอร์และสภาพแวดล้อมอุปกรณ์พกพาดังนั้นจึงปลอดภัยที่จะใช้

และด้วยฟังก์ชั่นไวยากรณ์ลูกศร ES6 มันยิ่งกระชับยิ่งขึ้น:

array.forEach(item => console.log(item));

ฟังก์ชั่นลูกศรยังมีการใช้งานอย่างกว้างขวางนอกจากว่าคุณวางแผนที่จะสนับสนุนแพลตฟอร์มโบราณ (เช่น IE11) คุณยังปลอดภัยที่จะไป

ข้อดี

  • สั้นและสั้นมาก
  • ที่เปิดเผย

จุดด้อย

  • ไม่สามารถใช้break/continue

โดยปกติคุณสามารถแทนที่ความจำเป็นในการbreakออกจากลูปที่จำเป็นโดยการกรององค์ประกอบอาเรย์ก่อนทำการวนซ้ำตัวอย่างเช่น:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

โปรดจำไว้ว่าคุณกำลังทำซ้ำอาร์เรย์เพื่อสร้างอาร์เรย์อื่นจากมันคุณควรใช้mapฉันเคยเห็นรูปแบบการต่อต้านนี้มาหลายครั้งแล้ว

ต่อต้านรูปแบบ:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

กรณีใช้แผนที่อย่างถูกต้อง:

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

นอกจากนี้หากคุณพยายามลดอาร์เรย์ให้เป็นค่าเช่นคุณต้องการหาผลรวมของตัวเลขคุณควรใช้วิธีการลด

ต่อต้านรูปแบบ:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

การใช้ที่เหมาะสมของการลด :

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. ES6 for-ofคำสั่ง

มาตรฐาน ES6 นำเสนอแนวคิดของวัตถุที่ทำซ้ำได้และกำหนดโครงสร้างใหม่สำหรับการสำรวจข้อมูล for...ofคำสั่ง

คำสั่งนี้ใช้ได้กับวัตถุที่ทำซ้ำชนิดใดก็ได้และสำหรับเครื่องกำเนิดไฟฟ้า (วัตถุใด ๆ ที่มี [Symbol.iterator]คุณสมบัติ)

วัตถุใน Array นั้นมีความสามารถในการกำหนด iterables ใน ES6 ดังนั้นคุณสามารถใช้คำสั่งนี้:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

ข้อดี

  • มันสามารถวนซ้ำวัตถุที่หลากหลายได้
  • สามารถใช้งบการควบคุมการไหลปกติ ( break/continue )
  • มีประโยชน์ในการย้ำค่าอะซิงโครนัสแบบซ้ำ ๆ

จุดด้อย

  • หากคุณกำหนดเป้าหมายเบราว์เซอร์รุ่นเก่าเอาท์พุท transpiled อาจทำให้คุณประหลาดใจ

ไม่ได้ใช้ for...in

@zipcodeman แนะนำให้ใช้for...inคำสั่ง แต่for-inควรหลีกเลี่ยงการวนซ้ำอาร์เรย์คำสั่งนั้นมีความหมายเพื่อระบุคุณสมบัติของวัตถุ

ไม่ควรใช้สำหรับวัตถุที่มีลักษณะคล้ายอาร์เรย์เนื่องจาก:

  • ไม่รับประกันคำสั่งของการวนซ้ำ ดัชนีอาร์เรย์อาจไม่ถูกเยี่ยมชมตามลำดับตัวเลข
  • คุณสมบัติที่สืบทอดจะระบุด้วย

จุดที่สองคือว่ามันสามารถทำให้คุณมีปัญหามากมายตัวอย่างเช่นถ้าคุณขยายArray.prototypeวัตถุเพื่อรวมวิธีการที่นั่นคุณสมบัตินั้นจะถูกระบุด้วย

ตัวอย่างเช่น:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

รหัสด้านบนจะบันทึกคอนโซล "a", "b", "c" และ "foo!"

นั่นเป็นปัญหาโดยเฉพาะอย่างยิ่งถ้าคุณใช้ห้องสมุดบางอย่างที่ต้องอาศัยการเพิ่มต้นแบบดั้งเดิม (เช่น MooTools เป็นต้น)

for-inคำสั่งที่ผมกล่าวว่าก่อนที่จะมีการระบุคุณสมบัติของวัตถุตัวอย่างเช่น:

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) { 
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

ในตัวอย่างข้างต้นhasOwnPropertyวิธีการช่วยให้คุณระบุคุณสมบัติของตัวเองเท่านั้นนั่นคือคุณสมบัติเฉพาะที่วัตถุมีร่างกายไม่มีคุณสมบัติที่สืบทอดมา

ฉันอยากจะแนะนำให้คุณอ่านบทความต่อไปนี้:


21
นี่คือเหตุผล (โดย CMS เขาด้วยตนเอง) stackoverflow.com/questions/1885317/…
OscarRyz

15
@ DoubleGras ฉันคิดว่านั่นเป็นความเห็นที่ทุกคนไม่ได้แบ่งปัน ดู: stackoverflow.com/questions/5752906/หรือgroups.google.com/forum/?fromgroups#!topic/jsmentors/?hl=th
Matthijs Wessels

3
ใครก็ตามที่คิดว่าคุณต้องการแคชความยาว ... โปรดดูคำตอบของฉันคุณไม่จำเป็นต้องเข้าถึงมันในครั้งเดียวปล่อยให้มันทำแคชคนเดียว: สำหรับ (var i = 0, item; item = myStringArray [i]; i ++) {/ * ใช้ไอเท็มที่นี่ * /}
Stijn de Witt

15
@StijndeWitt ไม่มีเพราะที่แบ่งหากคุณมี"falsey"ค่าในอาร์เรย์ของคุณ: false, undefined, 0, ,"" NaN
Phrogz

6
jsperf.com/caching-array-length/4 นี่คือการทดสอบเพื่อดูว่ามันคุ้มค่าที่จะแคชความยาวของอาร์เรย์ในลูป Javascript หรือไม่
Enrico

1114

ใช่สมมติว่าการใช้งานของคุณรวมถึงคุณลักษณะfor... ที่ofนำมาใช้ในECMAScript 2015 (รุ่น "Harmony") ... ซึ่งเป็นข้อสันนิษฐานที่ปลอดภัยในทุกวันนี้

มันได้ผลเช่นนี้:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

หรือดีกว่านั้นเนื่องจาก ECMAScript 2015 ยังมีตัวแปรที่กำหนดขอบเขตบล็อก:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

(ตัวแปรsนั้นแตกต่างกันไปในการทำซ้ำแต่ละครั้ง แต่ยังสามารถประกาศconstในส่วนเนื้อหาของลูปได้ตราบใดที่ไม่มีการแก้ไข)

หมายเหตุเกี่ยวกับอาร์เรย์เบาบาง: อาร์เรย์ใน JavaScript อาจไม่ได้เก็บไว้เป็นรายการหลายรายการตามการรายงานของlength; ว่าจำนวนที่รายงานเป็นเพียงหนึ่งเป็นใหญ่กว่าดัชนีสูงสุดที่ค่าจะถูกเก็บไว้ ถ้าอาร์เรย์เก็บองค์ประกอบน้อยกว่าที่ระบุโดยความยาวของมันจะมีค่าน้อยกว่า ตัวอย่างเช่นการมีอาร์เรย์ที่มีรายการเฉพาะที่ดัชนี 3, 12 และ 247 นั้นถูกต้องตามกฎหมายอย่างสมบูรณ์ สำหรับองค์ประกอบที่ขาดหายไปหรือไม่หรือคุณเพียงต้องการที่จะดำเนินการองค์ประกอบปัจจุบันได้จริง? มีแอปพลิเคชั่นมากมายสำหรับทั้งสองวิธี ขึ้นอยู่กับสิ่งที่คุณกำลังใช้อาร์เรย์lengthของอาร์เรย์ดังกล่าวมีรายงานว่า 248 แม้ว่ามันจะเป็นเพียงการจัดเก็บจริง 3 ค่า หากคุณพยายามเข้าถึงรายการที่ดัชนีอื่น ๆ อาร์เรย์จะมีundefinedค่าอยู่ที่นั่น ดังนั้นเมื่อคุณต้องการที่จะ "วนรอบ" อาเรย์คุณมีคำถามที่จะตอบ: คุณต้องการที่จะวนลูปในช่วงเต็มรูปแบบที่ระบุโดยความยาวและกระบวนการของมันundefined

ถ้าคุณวนซ้ำอาร์เรย์ด้วยfor.. ofเนื้อความของลูปจะถูกเรียกใช้งานlengthครั้งและตัวแปรควบคุมการวนซ้ำถูกตั้งค่าเป็นundefinedสำหรับรายการใด ๆ ที่ไม่ได้มีอยู่จริงในอาร์เรย์ ขึ้นอยู่กับรายละเอียดของรหัส "ทำบางสิ่งบางอย่างด้วย" พฤติกรรมนั้นอาจเป็นสิ่งที่คุณต้องการ แต่ถ้าไม่คุณควรใช้วิธีการอื่น

ของหลักสูตรนักพัฒนาบางส่วนไม่มีทางเลือก แต่จะใช้วิธีการที่แตกต่างกันต่อไปเพราะเหตุผลใดที่พวกเขากำลังกำหนดเป้าหมายรุ่นของ JavaScript ที่ยังไม่ได้รับการสนับสนุน...forof

ตราบใดที่การใช้งาน JavaScript ของคุณเป็นไปตามข้อกำหนดECMAScript รุ่นก่อนหน้า (ซึ่งเป็นกฎเช่นรุ่นของ Internet Explorer ก่อน 9) จากนั้นคุณสามารถใช้Array#forEachวิธีการวนซ้ำแทนการวนซ้ำ ในกรณีนั้นคุณจะส่งผ่านฟังก์ชั่นที่จะเรียกใช้ในแต่ละรายการในอาร์เรย์:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

ซึ่งแตกต่างจากfor... of, .forEachเพียงเรียกฟังก์ชันสำหรับองค์ประกอบที่เป็นจริงในปัจจุบันในอาร์เรย์ หากผ่านอาร์เรย์สมมุติฐานของเราที่มีสามองค์ประกอบและความยาว 248 มันจะเรียกฟังก์ชั่นสามครั้งเท่านั้นไม่ใช่ 248 ครั้ง นอกจากนี้ยังแยกความแตกต่างระหว่างองค์ประกอบที่หายไปและองค์ประกอบที่ตั้งค่าเป็นจริงundefined; สำหรับหลังมันจะยังคงเรียกใช้ฟังก์ชันส่งผ่านundefinedเป็นอาร์กิวเมนต์ ถ้านี่เป็นวิธีที่คุณต้องการที่จะจัดการกับอาร์เรย์เบาบาง.forEachอาจจะเป็นวิธีที่จะไปแม้ว่าสนับสนุนล่ามของคุณ...forof

ตัวเลือกสุดท้ายซึ่งทำงานในทุกรุ่นของ JavaScript เป็นห่วงการนับอย่างชัดเจน คุณเพียงแค่นับจาก 0 ถึงน้อยกว่าหนึ่งความยาวและใช้ตัวนับเป็นดัชนี ห่วงพื้นฐานดูเหมือนว่า:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

ข้อดีอย่างหนึ่งของวิธีนี้คือคุณสามารถเลือกวิธีการจัดการกับอาร์เรย์เบาบาง รหัสดังกล่าวจะทำงานร่างกายของวงที่เต็มรูปแบบlengthครั้งกับsชุดundefinedสำหรับองค์ประกอบที่ขาดหายไปเช่นเดียว..for ofหากคุณต้องการจัดการเฉพาะองค์ประกอบที่มีอยู่จริงของ sparse array เช่น.forEachคุณสามารถเพิ่มการinทดสอบอย่างง่าย ๆในดัชนี:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

การกำหนดค่าความยาวให้กับตัวแปรโลคัล (เมื่อเทียบกับการรวมการmyStringArray.lengthแสดงออกเต็มรูปแบบในเงื่อนไขลูป) สามารถสร้างความแตกต่างอย่างมีนัยสำคัญในประสิทธิภาพเนื่องจากมันข้ามการค้นหาคุณสมบัติในแต่ละครั้งผ่าน; เมื่อใช้ Rhino กับเครื่องของฉันความเร็วจะเพิ่มขึ้น 43%

คุณอาจเห็นการแคชความยาวทำได้ในประโยคการเตรียมใช้งานลูปเช่นนี้:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

ลูปการนับที่ชัดเจนยังหมายความว่าคุณสามารถเข้าถึงดัชนีของแต่ละค่าได้หากคุณต้องการ ดัชนีจะถูกส่งเป็นพารามิเตอร์พิเศษสำหรับฟังก์ชันที่คุณส่งผ่านforEachดังนั้นคุณสามารถเข้าถึงได้ด้วยวิธีดังกล่าวเช่นกัน:

myStringArray.forEach( function(s, i) {
   // ... do something with s and i ...
});

for... ofไม่ได้ให้ดัชนีที่เกี่ยวข้องกับแต่ละวัตถุ แต่ตราบใดที่วัตถุที่คุณทำซ้ำนั้นเป็นจริงArray( for.. ใช้ofงานได้สำหรับประเภทการวนซ้ำอื่น ๆ ซึ่งอาจไม่มีวิธีนี้) คุณสามารถใช้Array #entriesวิธีการเปลี่ยนเป็นอาร์เรย์ของคู่ [index, item] จากนั้นทำซ้ำมากกว่านั้น:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

for... inไวยากรณ์เอ่ยถึงคนอื่น ๆ สำหรับการวนลูปกับคุณสมบัติของวัตถุ; เนื่องจาก Array ใน JavaScript เป็นเพียงวัตถุที่มีชื่อคุณสมบัติตัวเลข (และlengthคุณสมบัติที่อัปเดตอัตโนมัติ) คุณจึงสามารถวนลูป Array กับ Array ได้ แต่ปัญหาคือมันไม่ได้ จำกัด ตัวเองให้อยู่ในค่าคุณสมบัติตัวเลข (โปรดจำไว้ว่าวิธีการแม้เป็นเพียงคุณสมบัติที่มีค่าปิด) และไม่รับประกันว่าจะวนซ้ำตามลำดับตัวเลข ดังนั้นไม่ควรใช้ไวยากรณ์for... สำหรับการวนซ้ำผ่านอาร์เรย์in


21
โปรดทราบว่าล่ามบางตัว (เช่น V8) จะแคชความยาวของอาร์เรย์โดยอัตโนมัติหากรหัสนั้นมีเวลาเพียงพอและตรวจพบว่าความยาวไม่ได้ถูกแก้ไขโดยลูป แม้ว่าการแคชความยาวจะยังคงดี แต่อาจไม่ได้เพิ่มความเร็วเมื่อโค้ดของคุณถูกเรียกใช้เวลาเพียงพอที่จะสร้างความแตกต่าง
Phrogz

2
@ mark-reed คุณช่วยอธิบายได้ไหมว่าทำไมคุณถึงใช้i in myStringArrayในตัวอย่างของคุณ? มันจะเป็นเท็จได้อย่างไร?
เดนิส V

2
@DenisV: false a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } เอาต์พุต 0, 1, 3 และ 4 a.lengthยังคงเป็น 5
Mark Reed

1
for j in aฉันไม่ได้บอก ฉันแสดงให้เห็นว่าinเช็คไม่ได้ซ้ำซ้อนตามที่คุณอ้างว่าเป็นโดยการแสดงดัชนีทั้งหมดและแสดงว่ามีค่าอยู่ระหว่าง 0 ถึงlength-1ไม่ได้อยู่ที่นั่น ฉันสามารถพิมพ์2 in aได้ซึ่งก็เป็นจริงfalseแม้ว่าคุณจะบอกว่ามันเป็นไปไม่ได้
Mark Reed

2
@GrijeshChauhan - ถูกต้อง ตัวอย่างเช่น IE ถึงเวอร์ชัน 8 ไม่สนับสนุน ดูคำถามนี้
Mark Reed

442

คุณสามารถใช้mapซึ่งเป็นเทคนิคการเขียนโปรแกรมการทำงานที่ยังมีอยู่ในภาษาอื่น ๆ เช่นงูหลามและHaskell

[1,2,3,4].map( function(item) {
     alert(item);
})

ไวยากรณ์ทั่วไปคือ:

array.map(func)

โดยทั่วไปfuncจะใช้หนึ่งพารามิเตอร์ซึ่งเป็นรายการของอาร์เรย์ แต่ในกรณีของ JavaScript ก็สามารถใช้พารามิเตอร์ที่สองซึ่งเป็นดัชนีของรายการและพารามิเตอร์ที่สามซึ่งเป็นอาร์เรย์ตัวเอง

ค่าส่งคืนของarray.mapคืออาร์เรย์อื่นดังนั้นคุณสามารถใช้มันได้

var x = [1,2,3,4].map( function(item) {return item * 10;});

และตอนนี้ x [10,20,30,40]คือ

คุณไม่จำเป็นต้องเขียนฟังก์ชั่นอินไลน์ มันอาจเป็นฟังก์ชั่นแยกต่างหาก

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

ซึ่งจะเรียงลำดับของเทียบเท่ากับ:

 for (item in my_list) {item_processor(item);}

new_listยกเว้นคุณไม่ได้รับ


7
ไม่ แต่มันมีพลังมากกว่านี้ ตรวจสอบนี้: joelonsoftware.com/items/2006/08/01.html
hasen

97
Array.forEachตัวอย่างเฉพาะที่อาจจะดีกว่าจะดำเนินการใช้ mapใช้สำหรับสร้างอาร์เรย์ใหม่
harto

21
@hasen ที่Array.prototype.mapวิธีการเป็นส่วนหนึ่งของมาตรฐานฉบับ ECMAScript 5 ยังไม่ได้มีอยู่ในการใช้งานทั้งหมด (เช่น IE ขาดมัน) ยังสำหรับการทำซ้ำมากกว่าอาร์เรย์ผมคิดว่าArray.prototype.forEachวิธีการที่เป็นมากกว่าความหมายที่ถูกต้อง ... นอกจากนี้ยังโปรดไม่' เสื้อแนะนำสำหรับในงบดูคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม :)
CMS

3
ความแตกต่างระหว่างforEachและmapคือเมื่อก่อนไม่ได้ผลลัพธ์ของการวนซ้ำ map(บางครั้ง aka collectแต่แตกต่างกันมากapply) นั้นมีไว้สำหรับแปลงองค์ประกอบของอาร์เรย์ให้เป็นผลลัพธ์ที่สอดคล้องกันอย่างชัดเจน มันคือการแมปแบบ 1 ต่อ 1 ดังนั้นชื่อ เป็นส่วนหนึ่งของการดำเนินงานทั้งหมดในตระกูลซึ่งรวมถึงreduce(ซึ่งสร้างผลลัพธ์เดียวจากทั้งอาร์เรย์) และfilter(ซึ่งสร้างชุดย่อยของอาร์เรย์ดั้งเดิม) และอื่น ๆ ในขณะที่forEachเพียงแค่ทำบางสิ่งบางอย่างกับแต่ละองค์ประกอบความหมายที่ไม่ได้ระบุ
Mark Reed

4
ลงคะแนนเพราะถ้าคุณไม่ได้ทำแผนที่อะไรจริง ๆ แล้วใช้ [] .map ทำให้เข้าใจผิด [] .forEach ทำให้เกิดความหมายและส่งผ่านอาร์กิวเมนต์สามตัวเดียวกันไปยังฟังก์ชัน
gengkev

120

ใน JavaScript ไม่แนะนำให้วนลูป Array ด้วย for-in loop แต่จะดีกว่าถ้าใช้forloop เช่น:

for(var i=0, len=myArray.length; i < len; i++){}

มันปรับให้เหมาะสมเช่นกัน ("แคช" ความยาวของอาร์เรย์) หากคุณต้องการที่จะเรียนรู้เพิ่มเติมอ่านโพสต์ของฉันเกี่ยวกับเรื่องนี้


2
myArray.forEach (ฟังก์ชั่น (obj) {}); ยังดีที่สุด
Jan Sverre

การปรับปรุงเล็กน้อย: คุณสามารถใช้++iแทนi++
roberkules

14
++iเป็นการเพิ่มประสิทธิภาพโรงเรียนเก่าที่คอมไพเลอร์สมัยใหม่ทำเพื่อคุณในการวนซ้ำมาเป็นเวลานาน :) stackoverflow.com/a/1547433/1033348
ngryman

6
คุณต้องระวังการใช้วงนี้ ฉันเริ่มใช้มันและมีปัญหาในการติดตามข้อผิดพลาดเพราะฉันทำผิดพลาดไปหนึ่งข้อ หากคุณรังสอง loops เช่นนี้jsfiddle.net/KQwmL/1 คุณต้องระวังที่จะตั้งชื่อ var len ให้แตกต่างกันในสองลูปมิฉะนั้นการวนซ้ำครั้งที่สองจะเขียนทับ len แรก
Rui Marques

1
รุยมาร์เกซ - คุณสามารถตั้งชื่อตัวแปรของคุณi_stopหรือแทนi_end lenมันอ่านได้ง่าย (ถ้าไม่มาก!) และคุณจะหลีกเลี่ยงปัญหาแบบนี้ (เนื่องจากวงอื่น ๆ ของคุณจะได้รับเช่นj_stop)
Chip Hogg

119

สำหรับ (ให้ s myStringArray) {

(ตอบคำถามของคุณโดยตรง: ตอนนี้คุณทำได้!)

คำตอบอื่น ๆ ส่วนใหญ่จะถูกต้อง แต่พวกเขาไม่ได้พูดถึง (เช่นการเขียนนี้) ที่ECMA Script  6  2015จะนำกลไกใหม่สำหรับการทำซ้ำที่for..ofห่วง

ไวยากรณ์ใหม่นี้เป็นวิธีที่ยอดเยี่ยมที่สุดในการทำซ้ำอาร์เรย์ใน javascript (ตราบใดที่คุณไม่ต้องการดัชนีการวนซ้ำ)

ปัจจุบันใช้งานได้กับ Firefox 13+, Chrome 37+ และไม่สามารถใช้งานร่วมกับเบราว์เซอร์อื่น ๆ (ดูความเข้ากันได้ของเบราว์เซอร์ด้านล่าง) โชคดีที่เรามีคอมไพเลอร์ JS (เช่นBabel ) ที่ให้เราใช้ฟีเจอร์รุ่นต่อไปในวันนี้

มันใช้งานได้บนโหนด (ฉันทดสอบในเวอร์ชั่น 0.12.0)

วนซ้ำอาร์เรย์

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

วนซ้ำอาร์เรย์ของวัตถุ

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

วนซ้ำตัวกำเนิด:

(ตัวอย่างที่แยกมาจากhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of )

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

ตารางความเข้ากันได้: http://kangax.github.io/es5-compat-table/es6/#For..of loops

ข้อมูลจำเพาะ: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}


หากคุณกำลังใช้ ES6 ฉันขอแนะนำให้const sแทนที่var s
joeytwiddle

ในการทดสอบของฉันในอาร์เรย์ขนาดใหญ่การใช้var s of arrเกือบสองเท่า (1.9x) เวลาดำเนินการเปรียบเทียบกับการใช้ตัวนับการวนรอบอย่างง่ายและการดึงองค์ประกอบโดยดัชนีใน nodejs
theferrit32

ทำไมเรื่องแปลก ๆ ในบรรทัดแรกและบรรทัดสุดท้าย?
ปีเตอร์มอร์เทนเซ่น

91

Opera, Safari, Firefox และ Chrome ในขณะนี้ทั้งหมดแบ่งปันชุดของวิธีการ Array ที่ปรับปรุงใหม่สำหรับการปรับลูปทั่วไปจำนวนมาก

คุณอาจไม่ต้องการทั้งหมด แต่ก็มีประโยชน์มากหรือจะเป็นถ้าเบราว์เซอร์ทุกตัวรองรับพวกเขา

Mozilla Labs เผยแพร่อัลกอริธึมที่ทั้งคู่และWebKitใช้เพื่อให้คุณสามารถเพิ่มได้ด้วยตนเอง

filterส่งคืนอาร์เรย์ของรายการที่ตรงตามเงื่อนไขหรือการทดสอบ

ทุก ๆผลตอบแทนจริงถ้าสมาชิกอาเรย์ทุกคนผ่านการทดสอบ

ผลตอบแทนบางส่วนเป็นจริงหากมีการทดสอบ

forEachจะเรียกใช้ฟังก์ชันในสมาชิกอาเรย์แต่ละตัวและจะไม่ส่งคืนอะไรเลย

mapเป็นเหมือน forEach แต่มันจะคืนค่าอาเรย์ของผลลัพธ์ของการดำเนินการสำหรับแต่ละองค์ประกอบ

วิธีการเหล่านี้ทั้งหมดใช้ฟังก์ชั่นสำหรับอาร์กิวเมนต์แรกของพวกเขาและมีอาร์กิวเมนต์ที่สองไม่จำเป็นซึ่งเป็นวัตถุที่มีขอบเขตที่คุณต้องการกำหนดสมาชิกอาร์เรย์ที่พวกเขาห่วงผ่านฟังก์ชั่น

ไม่ต้องสนใจจนกว่าคุณจะต้องการมัน

indexOfและlastIndexOfค้นหาตำแหน่งที่เหมาะสมขององค์ประกอบแรกหรือสุดท้ายที่ตรงกับอาร์กิวเมนต์

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();

1
เพิ่มเติม: IE รองรับ forEach ตั้งแต่รุ่น 9 ดูวิธีการแต่ละวิธี MSDN
rwitzel

75

Intro

ตั้งแต่เวลาในวิทยาลัยฉันได้ตั้งโปรแกรมใน Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ และอาจเป็นภาษาอื่น ๆ ที่ฉันนึกไม่ออกตอนนี้

ในขณะที่ทุกคนมีภาษาศาสตร์ของตัวเอง แต่ภาษาเหล่านี้แต่ละภาษาก็มีแนวคิดพื้นฐานที่เหมือนกันหลายประการ แนวคิดดังกล่าวรวมถึงโพรซีเดอร์ / ฟังก์ชั่น - สถานะIF, - FORลูปและ - WHILEลูป


แบบดั้งเดิม - forลูป

forวงแบบดั้งเดิมมีสามองค์ประกอบ:

  1. การเริ่มต้น:ดำเนินการก่อนที่บล็อกการค้นหาจะดำเนินการในครั้งแรก
  2. เงื่อนไข:ตรวจสอบเงื่อนไขทุกครั้งก่อนที่จะดำเนินการบล็อกลูปและออกจากลูปหากเป็นเท็จ
  3. ดำเนินการภายหลัง:ดำเนินการทุกครั้งหลังจากดำเนินการบล็อกลูป

ส่วนประกอบทั้งสามนี้แยกจากกันด้วย;สัญลักษณ์ เนื้อหาสำหรับแต่ละองค์ประกอบทั้งสามนี้เป็นตัวเลือกซึ่งหมายความว่าต่อไปนี้เป็นforลูปที่น้อยที่สุดที่เป็นไปได้:

for (;;) {
    // Do stuff
}

แน่นอนว่าคุณจะต้องรวมif(condition === true) { break; } สิ่งif(condition === true) { return; }ใดสิ่งหนึ่งไว้ข้างในนั้นforเพื่อให้มันหยุดทำงาน

โดยทั่วไปแม้ว่าการกำหนดค่าเริ่มต้นจะใช้ในการประกาศดัชนีเงื่อนไขที่ใช้ในการเปรียบเทียบดัชนีนั้นกับค่าต่ำสุดหรือค่าสูงสุดและใช้ภายหลังเพื่อเพิ่มดัชนี:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

การใช้การforวนซ้ำแบบดั้งเดิมเพื่อวนซ้ำผ่านอาร์เรย์

วิธีดั้งเดิมในการวนซ้ำผ่านอาร์เรย์คือ:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

หรือถ้าคุณต้องการวนซ้ำไปข้างหลังคุณทำสิ่งนี้:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

อย่างไรก็ตามมีความเป็นไปได้หลายรูปแบบเช่นในตัวอย่างนี้:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... หรืออันนี้ ...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

... หรืออันนี้:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

สิ่งที่ได้ผลดีที่สุดส่วนใหญ่เป็นเรื่องของรสนิยมส่วนตัวและกรณีการใช้งานเฉพาะที่คุณกำลังนำไปใช้

โปรดทราบว่าแต่ละรูปแบบเหล่านี้ได้รับการสนับสนุนโดยเบราว์เซอร์ทั้งหมดรวมถึงรูปแบบที่เก่ามาก!


whileห่วง

ทางเลือกหนึ่งในการforวนซ้ำคือการwhileวนซ้ำ ในการวนซ้ำอาร์เรย์คุณสามารถทำได้:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

เช่นเดียวกับforลูปแบบดั้งเดิมลูwhileปได้รับการสนับสนุนแม้กระทั่งเบราว์เซอร์ที่เก่าแก่ที่สุด

นอกจากนี้โปรดทราบว่าขณะที่วนซ้ำสามารถเขียนใหม่เป็นforวนซ้ำได้ ตัวอย่างเช่นการwhileวนซ้ำที่นี่จะทำงานในลักษณะเดียวกันกับfor-loop นี้:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in และ for...of

ใน JavaScript คุณสามารถทำสิ่งนี้ได้:

for (i in myArray) {
    console.log(myArray[i]);
}

สิ่งนี้ควรใช้ด้วยความระมัดระวังเนื่องจากมันไม่ได้ทำงานเหมือนกับforวนลูปแบบดั้งเดิมในทุกกรณีและมีผลข้างเคียงที่อาจเกิดขึ้นที่ต้องพิจารณา ดูเหตุใดการใช้ "for ... in" กับการทำซ้ำอาร์เรย์จึงเป็นความคิดที่ไม่ดี สำหรับรายละเอียดเพิ่มเติม

เป็นทางเลือกกับผู้มีตอนนี้ยังfor...in for...ofตัวอย่างต่อไปนี้แสดงความแตกต่างระหว่างfor...ofลูปและfor...inลูป:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

นอกจากนี้คุณต้องพิจารณาว่าไม่มีรุ่นของ Internet Explorer ที่รองรับfor...of( Edge 12+ทำ) และfor...inต้องใช้อย่างน้อย Internet Explorer 10


Array.prototype.forEach()

ทางเลือกอื่นสำหรับfor-loops คือArray.prototype.forEach()ซึ่งใช้ไวยากรณ์ต่อไปนี้:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() ได้รับการสนับสนุนโดยเบราว์เซอร์ที่ทันสมัยทั้งหมดเช่นเดียวกับ Internet Explorer 9 และใหม่กว่า


ห้องสมุด

ท้ายที่สุดห้องสมุดสาธารณูปโภคหลายแห่งก็มีforeachรูปแบบของตนเองเช่นกัน AFAIK ทั้งสามที่เป็นที่นิยมที่สุดคือ:

jQuery.each()ในjQuery :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each()ในในUnderscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(), ในLodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});

68

ใช้ขณะที่ลูป ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

บันทึก: 'หนึ่ง', 'สอง', 'สาม'

และสำหรับการเรียงลำดับย้อนกลับนั้นวงที่มีประสิทธิภาพยิ่งขึ้น

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

บันทึก: 'สาม', 'สอง', 'หนึ่ง'

หรือforวงคลาสสิก

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

บันทึก: 'หนึ่ง', 'สอง', 'สาม'

การอ้างอิง: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/


21
ตัวอย่างแรกของไวยากรณ์ "while" จะไม่ทำงานหากองค์ประกอบอาเรย์ใด ๆ เป็นเท็จ
Chris Cooper

2
... และสิ่งนี้ในขณะที่วงจะเทียบเท่ากับ: สำหรับ (var i = 0, item; item = items [i]; i ++) ซึ่งจำเป็นต้องประกาศดัชนีและตัวแปรรายการไว้ล่วงหน้า ...
Stijn de Witt


39

หากคุณต้องการวิธีสั้น ๆ ในการเขียนลูปอย่างรวดเร็วและคุณสามารถทำซ้ำในสิ่งที่ตรงกันข้าม:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

สิ่งนี้มีประโยชน์ในการแคชความยาว (คล้ายfor (var i=0, len=myArray.length; i<len; ++i)และไม่เหมือนกันfor (var i=0; i<myArray.length; ++i)) ในขณะที่มีจำนวนอักขระน้อยลง

มีบางครั้งที่คุณควรทำซ้ำในสิ่งที่ตรงกันข้ามเช่นเมื่อวนซ้ำNodeList แบบสดที่คุณวางแผนจะลบไอเท็มออกจาก DOM ในระหว่างการทำซ้ำ


16
สำหรับคนที่ไม่ได้สิ่งที่แยบยล: การแสดงออกของ i - ถูกประเมินเป็นครั้งแรกและอนุญาตให้วนซ้ำดำเนินการต่อเมื่อไม่ผิดพลาด ... หลังจากนั้นตัวนับจะลดลง ทันทีที่ฉันกลายเป็นศูนย์มันจะแตกออกจากลูปเนื่องจากศูนย์เป็นค่าเท็จใน Javascript
Stijn de Witt

5
falsish? คุณหมายถึงความเท็จ ให้ทุกคนใช้คำศัพท์ที่เหมาะสมเพื่อหลีกเลี่ยงความสับสน;)
danwellman

4
ฉันเคยเห็นคำที่ไม่ถูกต้องถูกใช้โดยคนที่ฉันพิจารณาว่าเป็นผู้เชี่ยวชาญ ถ้ามันดีพอสำหรับพวกเขามันก็ดีพอสำหรับฉัน นอกจากนี้ยังผิดหวัง แต่ที่เห็นว่าความคิดเห็นของฉันที่จริง ontopic และเพิ่มคำอธิบาย / ความเข้าใจที่ได้รับ 0 upvotes แต่ความคิดเห็นที่ nitpicks ในคำในความคิดเห็นของฉันได้รับ 4. Ah ดีเพียงเรื่องของลำดับความสำคัญฉันเดา
Stijn de Witt

"แคชความยาว"? ความยาวจะถูกเก็บไว้เป็นจำนวนเต็มในอาร์เรย์โดยจะไม่วัดทุกครั้งที่คุณเข้าถึง ไม่มีประโยชน์ในการคัดลอกค่าความยาวไปยังตัวแปรอื่น
Mouscellaneous

1
@Mouscellaneous วันนี้มีไม่แน่นอน; ในหลายปีที่ผ่านมาการวนซ้ำ JavaScript ของแคชความยาวทางด้าน JavaScript (แทนที่จะไปถึงการใช้งาน) เป็นผลกำไรที่สมบูรณ์แบบที่ชัดเจน (เมื่อ microoptimizing) ยกตัวอย่างเช่นfor (var i=0,len=array.length;i<len;++i)เป็นเรื่องธรรมดาและเป็นห่วงในการเขียน
Phrogz

36

บางกรณีใช้วนลูปผ่านอาร์เรย์ในวิธีการเขียนโปรแกรมการทำงานใน JavaScript:

1. แค่วนรอบอาร์เรย์

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

หมายเหตุ: Array.prototype.forEach () ไม่ใช่วิธีการพูดอย่างเคร่งครัดเนื่องจากฟังก์ชั่นใช้เป็นพารามิเตอร์อินพุตไม่ควรส่งคืนค่าซึ่งไม่สามารถถือว่าเป็นฟังก์ชันที่แท้จริงได้

2. ตรวจสอบว่าองค์ประกอบใด ๆ ในอาร์เรย์ผ่านการทดสอบหรือไม่

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. แปลงเป็นอาเรย์ใหม่

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

หมายเหตุ: เมธอด map () จะสร้างอาร์เรย์ใหม่พร้อมกับผลลัพธ์ของการเรียกฟังก์ชันที่มีให้ในทุกองค์ประกอบในอาร์เรย์ที่เรียก

4. สรุปคุณสมบัติเฉพาะและคำนวณค่าเฉลี่ย

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. สร้างอาร์เรย์ใหม่ตามต้นฉบับ แต่ไม่มีการแก้ไข

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. นับจำนวนของแต่ละหมวดหมู่

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. ดึงเซตย่อยของอาร์เรย์ตามเกณฑ์เฉพาะ

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

หมายเหตุ: เมธอด filter () จะสร้างอาร์เรย์ใหม่พร้อมองค์ประกอบทั้งหมดที่ผ่านการทดสอบที่ใช้งานโดยฟังก์ชันที่ให้ไว้

8. เรียงลำดับอาร์เรย์

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

ป้อนคำอธิบายรูปภาพที่นี่

9. ค้นหาองค์ประกอบในอาร์เรย์

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

ป้อนคำอธิบายรูปภาพที่นี่

กระบวนการ Array.prototype.find () วิธีการคืนค่าขององค์ประกอบแรกในอาร์เรย์ที่ตอบสนองฟังก์ชั่นการทดสอบที่ให้ไว้

อ้างอิง


30

มีวิธีการทำที่คุณมีขอบเขตโดยนัยน้อยมากในวงของคุณและทำไปกับตัวแปรพิเศษ

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

หรือถ้าคุณต้องการได้รับ id และมีforวงวนคลาสสิก

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

เบราว์เซอร์ที่ทันสมัยทุกวิธีการสนับสนุน iterator forEach, map, reduce, filterและโฮสต์ของวิธีการอื่น ๆ ในต้นแบบอาร์เรย์


3
โปรดทราบว่าล่ามบางตัว (เช่น V8) จะแคชความยาวของอาร์เรย์โดยอัตโนมัติหากรหัสนั้นมีเวลาเพียงพอและตรวจพบว่าความยาวไม่ได้ถูกแก้ไขโดยลูป
Phrogz

ขอบคุณสำหรับข้อมูล @Phrogz มันเป็นความจริงที่มีการปรับแต่งมากมายที่ VM สามารถทำได้ แต่เนื่องจากเบราว์เซอร์รุ่นเก่าไม่มีสิ่งนี้มันจะเป็นการปฏิบัติที่ดีที่สุดในการปรับให้เหมาะสมเนื่องจากมีราคาถูกมาก
Gabriel

1
@Gabriel: ทำไมล่ะ โปรดยกตัวอย่างโลกแห่งความจริงที่แสดงว่าการไม่แคชความยาวเป็นคอขวดของประสิทธิภาพ ฉันทำตาม 'การเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากของความชั่วร้ายทั้งหมด " ฉันจะแก้ไขว่าหนึ่งในวงที่จริง poses ปัญหาเมื่อผมพบมัน ...
Stijn เดอวิตต์

1
@StijndeWitt imo มันเป็นเพียงปัญหาโวหาร จริงๆแล้วฉันไม่ได้ใช้ลูปแทนการใช้ขีดเส้นใต้แทนสิ่งต่าง ๆ เช่น _.each, _.map เป็นต้นเพื่อทำสิ่งเหล่านี้อีกต่อไป เมื่อฉันเขียนลูปแบบนี้ฉันจะเก็บความยาวเป็นหลักเพื่อให้การประกาศตัวแปรทั้งหมดของฉันอยู่ในที่เดียวที่ด้านบนของฟังก์ชั่นของฉัน การปฏิบัติตามคำแนะนำของฉันในเรื่องนี้ไม่สำคัญกับแอปพลิเคชันโลกแห่งความจริงใด ๆ การเพิ่มประสิทธิภาพก่อนวัยอันควรแย่มาก แต่ถ้าการเพิ่มประสิทธิภาพเกิดขึ้นจากการตัดสินใจแบบโวหารฉันไม่คิดว่ามันจะเป็นเรื่องสำคัญ
Gabriel

1
@Gabriel ฉันเชื่อว่า JavaScript รองรับฟังก์ชั่นแผนที่ในอาร์เรย์แล้วไม่จำเป็นต้องแนะนำ lib เพิ่มเติมสำหรับสิ่งนั้น
Noz

28

มีหลายวิธีในการวนซ้ำในอาร์เรย์ใน JavaScript

ทั่วไปห่วง:

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

for5 ของ ES5:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

ดูที่นี่สำหรับข้อมูลโดยละเอียดหรือคุณสามารถตรวจสอบMDNสำหรับการวนซ้ำในอาร์เรย์ใน JavaScript และใช้ jQuery check jQuery สำหรับแต่ละรายการ


27

ฉันแนะนำให้ใช้ไลบรารีunderscore.jsอย่างละเอียด มันให้ฟังก์ชั่นต่าง ๆ ที่คุณสามารถใช้เพื่อวนซ้ำอาร์เรย์ / คอลเลกชัน

ตัวอย่างเช่น

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...

7
สำหรับผู้ค้นพบใหม่ของคำถามนี้ฉันอยากจะชี้ให้เห็นว่าLo-Dashผู้สืบทอดฝ่ายจิตวิญญาณของ Underscore ที่พัฒนาขึ้นมาในหลาย ๆ ด้าน
Mark Reed

3
เหตุใดจึงต้องใช้underscoreถ้าECMA-262ได้รับการเพิ่มตัวทำforEachละลาย รหัสเนทีฟดีกว่าเสมอ
Walter Chapilliquen - wZVanG

27

ห่วงอาร์เรย์:

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

ห่วงวัตถุ:

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}

27

ใช่คุณสามารถทำเช่นเดียวกันใน JavaScript โดยใช้การวนซ้ำ แต่ไม่ จำกัด เพียงนั้นมีหลายวิธีในการวนซ้ำอาร์เรย์ใน JavaScript ลองนึกภาพคุณมีอาร์เรย์ด้านล่างนี้และคุณต้องการวนซ้ำมัน:

var arr = [1, 2, 3, 4, 5];

นี่คือโซลูชั่น:

1) สำหรับวง

การforวนซ้ำเป็นวิธีการวนลูปทั่วไปผ่านอาร์เรย์ใน JavaScript แต่ไม่ถือว่าเป็นวิธีแก้ปัญหาที่เร็วที่สุดสำหรับอาร์เรย์ขนาดใหญ่:

for (var i=0, l=arr.length; i<l; i++) {
  console.log(arr[i]);
}

2) ในขณะที่วง

A while loop ถือเป็นวิธีที่เร็วที่สุดในการวนลูปผ่านอาร์เรย์ที่มีความยาว แต่โดยปกติจะใช้น้อยกว่าในรหัส JavaScript:

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3) ทำในขณะที่
A do whileกำลังทำสิ่งเดียวwhileกับที่มีความแตกต่างของไวยากรณ์ดังนี้:

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

นี่เป็นวิธีหลักในการทำลูป JavaScript แต่มีอีกสองสามวิธีในการทำเช่นนั้น

นอกจากนี้เรายังใช้ for inวนซ้ำสำหรับการวนซ้ำวัตถุใน JavaScript

นอกจากนี้ยังมองไปที่map(), filter(), reduce()ฯลฯ ฟังก์ชั่นบนอาร์เรย์ใน JavaScript พวกเขาอาจทำสิ่งต่าง ๆ ได้เร็วกว่าและดีกว่าการใช้whileและforและ

นี่เป็นบทความที่ดีถ้าคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับฟังก์ชันอะซิงโครนัสผ่านอาร์เรย์ใน JavaScript

การเขียนโปรแกรมฟังก์ชั่นได้รับการทำให้ค่อนข้างสาดในโลกการพัฒนาวันนี้ และด้วยเหตุผลที่ดีเทคนิคการใช้งานสามารถช่วยให้คุณเขียนรหัสที่เปิดเผยได้มากขึ้นซึ่งง่ายต่อการเข้าใจได้อย่างรวดเร็วรีแฟคเตอร์และการทดสอบ

หนึ่งในสิ่งสำคัญของการเขียนโปรแกรมฟังก์ชั่นคือการใช้รายการและการดำเนินงานรายการพิเศษ และสิ่งเหล่านั้นเป็นสิ่งที่เสียงเหมือน: อาร์เรย์ของสิ่งต่าง ๆ และสิ่งที่คุณทำกับพวกเขา แต่ความคิดเชิงหน้าที่นั้นปฏิบัติต่อพวกเขาแตกต่างไปเล็กน้อยจากที่คุณคาดหวัง

บทความนี้จะดูสิ่งที่ฉันชอบเรียกการดำเนินการรายการ "ใหญ่สาม" อย่างใกล้ชิด: แผนที่ตัวกรองและลด การห่อหัวของคุณรอบฟังก์ชั่นทั้งสามนี้เป็นขั้นตอนสำคัญต่อความสามารถในการเขียนโค้ดฟังก์ชั่นที่สะอาดตา

นอกจากนี้ยังหมายความว่าคุณจะไม่ต้องเขียนวนซ้ำอีก

อ่านเพิ่มเติม >> ที่นี่ :


มีความแตกต่างด้านประสิทธิภาพการทำงานก่อนการวนซ้ำและการวนซ้ำสักครู่เมื่อวนซ้ำผ่านอาร์เรย์หรือไม่ ฉันอยู่ภายใต้ความประทับใจความแตกต่างส่วนใหญ่เป็นประโยค
เชีย

24

หากใครสนใจด้านประสิทธิภาพของกลไกหลายอย่างที่มีให้สำหรับการทำซ้ำ Array ฉันได้เตรียมการทดสอบ JSPerf ต่อไปนี้:

https://jsperf.com/fastest-array-iterator

ผลการปฏิบัติงาน

ผล:

แบบดั้งเดิมfor()iterator คือไกลโดยวิธีที่เร็วที่สุดโดยเฉพาะอย่างยิ่งเมื่อนำมาใช้กับแคชยาวอาร์เรย์

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // Do something
}

Array.prototype.forEach()และArray.prototype.map()วิธีการที่มีการประมาณที่ช้าที่สุดอาจเป็นผลมาจากการที่ค่าใช้จ่ายในการเรียกใช้ฟังก์ชัน


ดีกว่าใช้i = i +1แทนi++
DarckBlezzer

2
สามารถปรับปรุงได้: โปรดใช้: ++ i แทน i ++ สิ่งนี้จะหลีกเลี่ยงวัตถุชั่วคราว ดังนั้นจึงลดการใช้หน่วยความจำและเวลา cpu (ไม่จำเป็นต้องจัดสรร)!
PowerStat

@PowerStat คุณสามารถให้ลิงค์หรือการอ้างอิงเกี่ยวกับเรื่องนี้ได้หรือไม่? ฉันไม่เคยได้ยินเรื่องนี้เลยฟังดูน่าสนใจ ...
colxi

1
@ colxi สำหรับสิ่งที่น่าสนใจเช่นนี้คุณควรอ่านสิ่งที่ไม่ยอมใครง่ายๆ C ++ จาก Herb Sutter และ Scott Meyers ++ i vs i ++ สิ่งนั้นมาจากหนังสือ: เจ๋ง C ++: 47 ปริศนาทางคณิตศาสตร์ , ปัญหาการเขียนโปรแกรมและการแก้ปัญหา - ฉันสามารถหามันได้ที่gotw.caแต่สามารถพิสูจน์ได้สำหรับการเขียนโปรแกรมภาษาทุกภาษา
PowerStat

21

หากคุณใช้ไลบรารี jQuery ให้ลองใช้ http://api.jquery.com/jQuery.each/

จากเอกสาร:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

คืนค่า: วัตถุ

รายละเอียด: ฟังก์ชั่นตัววนซ้ำทั่วไปซึ่งสามารถใช้ในการวนซ้ำอย่างกลมกลืนกับวัตถุและอาร์เรย์ อาร์เรย์และวัตถุที่มีลักษณะคล้ายอาร์เรย์ที่มีคุณสมบัติความยาว (เช่นวัตถุอาร์กิวเมนต์ของฟังก์ชัน) ทำซ้ำโดยดัชนีตัวเลขจาก 0 ถึงความยาว 1 วัตถุอื่น ๆ มีการทำซ้ำผ่านคุณสมบัติที่มีชื่อของพวกเขา

$.each()ฟังก์ชั่นไม่ได้เป็นเช่นเดียวกับ$(selector).each()ที่จะใช้ในการย้ำเฉพาะมากกว่าวัตถุ jQuery $.each() ฟังก์ชั่นที่สามารถใช้เพื่อย้ำกว่าคอลเลกชันใด ๆ ไม่ว่าจะเป็นแผนที่ (วัตถุจาวาสคริปต์) หรืออาร์เรย์ ในกรณีของอาร์เรย์การเรียกกลับจะถูกส่งผ่านดัชนีอาร์เรย์และค่าอาร์เรย์ที่สอดคล้องกันในแต่ละครั้ง (ค่าสามารถเข้าถึงได้ผ่านthisคำหลัก แต่ Javascript จะล้อมthisค่าเป็นเสมอObjectแม้ว่าจะเป็นสตริงหรือค่าตัวเลขแบบธรรมดา) เมธอดจะส่งคืนอาร์กิวเมนต์แรกซึ่งเป็นวัตถุที่ถูกทำซ้ำ


9
jQuery สำหรับทุกสิ่งใช่ไหม
ข้อยกเว้น

6
เห็นด้วยกับข้อยกเว้น อย่าประมาทผลกระทบของการพึ่งพาพิเศษ ฉันจะแนะนำต่อสิ่งนี้ยกเว้นในรหัสที่ใช้ jQuery อย่างหนักอยู่แล้ว
Stijn de Witt

2
อัปเดต: วันนี้คุณสามารถใช้Array.forEachเพื่อรับเอฟเฟกต์เดียวกันกับอาร์เรย์ดั้งเดิม
Stijn de Witt

20

ฉันยังไม่เห็นการเปลี่ยนแปลงนี้ซึ่งโดยส่วนตัวแล้วฉันชอบสิ่งที่ดีที่สุด:

รับอาร์เรย์:

var someArray = ["some", "example", "array"];

คุณสามารถวนซ้ำมันได้โดยไม่ต้องเข้าถึงคุณสมบัติความยาว:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

ดู JsFiddle นี้แสดงให้เห็นว่า: http://jsfiddle.net/prvzk/

ใช้งานได้กับอาร์เรย์ที่ไม่กระจายเท่านั้น หมายความว่ามีค่าในแต่ละดัชนีในอาร์เรย์ อย่างไรก็ตามฉันพบว่าในทางปฏิบัติฉันแทบจะไม่เคยใช้อาร์เรย์เบาบางใน JavaScript ... ในกรณีเช่นนี้มักจะใช้วัตถุเป็นแผนที่ / hashtable ได้ง่ายกว่ามาก หากคุณมีอาร์เรย์ที่กระจัดกระจายและต้องการวนซ้ำมากกว่า 0 .. length-1 คุณต้องการโครงสร้าง (var i = 0; i <someArray.length; ++ i) สร้าง แต่คุณยังต้องการifวงใน เพื่อตรวจสอบว่าองค์ประกอบที่ดัชนีปัจจุบันมีการกำหนดจริง

นอกจากนี้ตามที่ CMS ระบุไว้ในความคิดเห็นด้านล่างคุณสามารถใช้สิ่งนี้กับอาร์เรย์ที่ไม่มีค่าที่ไม่ถูกต้องเท่านั้น อาร์เรย์ของสตริงจากตัวอย่างใช้งานได้ แต่ถ้าคุณมีสตริงว่างหรือตัวเลขที่เป็น 0 หรือ NaN เป็นต้นวงจะแตกออกก่อนกำหนด ในทางปฏิบัติแล้วนี่เป็นปัญหาสำหรับฉัน แต่มันก็เป็นสิ่งที่คุณควรคำนึงถึงซึ่งทำให้นี่เป็นวงที่ต้องคิดถึงก่อนที่คุณจะใช้ ... ซึ่งอาจทำให้บางคนไม่ได้ผล :)

สิ่งที่ฉันชอบเกี่ยวกับวงนี้คือ:

  • มันสั้นที่จะเขียน
  • ไม่จำเป็นต้องเข้าถึงคุณสมบัติความยาว
  • รายการที่จะเข้าถึงจะถูกกำหนดโดยอัตโนมัติภายในตัวลูปภายใต้ชื่อที่คุณเลือก
  • รวมกันอย่างเป็นธรรมชาติมากกับ array.push และ array.splice เพื่อใช้อาร์เรย์เช่น list / stack

เหตุผลที่ใช้งานได้ก็คือข้อมูลจำเพาะของอาเรย์กำหนดว่าเมื่อคุณอ่านรายการจากดัชนี> = ความยาวของอาเรย์มันจะกลับมาไม่ได้กำหนด เมื่อคุณเขียนไปยังตำแหน่งดังกล่าวสถานที่นั้นจะทำการอัพเดตความยาว

สำหรับฉันการสร้างนี้เลียนแบบไวยากรณ์ของ Java 5 ที่ฉันชอบมากที่สุด:

for (String item : someArray) {
}

... ด้วยสิทธิประโยชน์เพิ่มเติมของการรู้เกี่ยวกับดัชนีปัจจุบันภายในลูป


13
ขอให้สังเกตว่าด้วยวิธีนี้วงจะหยุดเร็ว ๆ นี้ก็พบว่าค่า falseyเช่นสตริงว่าง0, false, NaN, nullหรือundefinedแม้กระทั่งก่อนiถึงยาวเช่น: jsfiddle.net/prvzk/1
CMS

3
(item=someArray[i]) !== undefinedเงื่อนไขห่วงอาจจะ
daniel1426

18

มีวิธีการทำซ้ำมากกว่าคุณสมบัติของวัตถุเท่านั้นไม่รวมถึงคุณสมบัติของต้นแบบ:

for (var i in array) if (array.hasOwnProperty(i)) {
    // Do something with array[i]
}

แต่มันจะยังคงย้ำคุณสมบัติที่กำหนดเอง

ใน JavaScript คุณสมบัติที่กำหนดเองสามารถกำหนดให้กับวัตถุใด ๆ รวมถึงอาร์เรย์

หากต้องการย้ำกว่าอาร์เรย์แยกfor (var i = 0; i < array.length; i++) if (i in array)หรือarray.forEachด้วยes5shimควรจะใช้


และวิธีการเกี่ยวกับการใช้งานfor (var i in array) if (++i)?
Daniel Sokolowski

15

มีสองวิธีใน JavaScript สองตัวอย่างแรกคือตัวอย่าง JavaScript อันที่สามใช้ประโยชน์จากไลบรารี JavaScript นั่นคือ jQuery ใช้ประโยชน์จาก.each()ฟังก์ชัน

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


for...inควรหลีกเลี่ยงวัตถุที่มีลักษณะคล้ายอาร์เรย์
brk

15

วิธีที่สง่างามและรวดเร็วที่สุด

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


แก้ไขแล้ว (เพราะฉันผิด)


การเปรียบเทียบวิธีการวนลูปผ่านอาร์เรย์ของรายการ 100,000 รายการและทำการดำเนินการขั้นต่ำด้วยค่าใหม่ในแต่ละครั้ง

เตรียม:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

แบบทดสอบ:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>

การวนซ้ำนี้ดูเหมือนจะไม่เป็นไปตามลำดับของรายการในอาร์เรย์
Deniz Ozger

การทดสอบของฉันผิด ถูกต้องแสดงทั้งหมด LOOPS ในขณะนี้ jsperf.com/native-loop-performance/16
molokoloco

@bergi ถูกต้อง การวนซ้ำนี้จะลบล้างอาร์เรย์ในขณะที่ลูปผ่าน ไม่ใช่สิ่งที่คุณต้องการในกรณีส่วนใหญ่
Stijn de Witt

4
แบ่งในรายการปลอม
njzk2

12

แนวทางที่ดีที่สุดคือการแคชความยาวของอาเรย์และการใช้รูปแบบ var เดียวเริ่มต้นตัวแปรทั้งหมดด้วยคำหลักวาร์เดียว

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

หากคำสั่งของการวนซ้ำไม่สำคัญเกินกว่าที่คุณควรลองวนรอบย้อนกลับมันจะเร็วที่สุดเพราะจะลดการทดสอบสภาพค่าใช้จ่ายและการลดลงจะอยู่ในคำสั่งเดียว:

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

หรือดีกว่าและสะอาดกว่าเมื่อใช้ลูป:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}

12

ใน JavaScript มีโซลูชั่นมากมายในการวนรอบอาร์เรย์

รหัสด้านล่างเป็นรหัสยอดนิยม

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()


12

หากคุณต้องการใช้ jQuery มีตัวอย่างที่ดีในเอกสารประกอบ:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });

12

วิธีที่ดีที่สุดในความคิดของฉันคือการใช้ฟังก์ชัน Array.forEach หากคุณไม่สามารถใช้งานได้ฉันขอแนะนำให้รับ polyfill จาก MDN เพื่อให้พร้อมใช้งานเป็นวิธีที่ปลอดภัยที่สุดในการวนซ้ำอาร์เรย์ใน JavaScript

Array.prototype.forEach ()

ดังนั้นตามที่คนอื่น ๆ แนะนำนี่เป็นสิ่งที่คุณต้องการ:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

สิ่งนี้ทำให้มั่นใจได้ว่าทุกสิ่งที่คุณต้องการในขอบเขตของการประมวลผลอาเรย์ยังคงอยู่ภายในขอบเขตนั้นและคุณเพียงประมวลผลค่าของอาเรย์เท่านั้นไม่ใช่คุณสมบัติของวัตถุและสมาชิกอื่น ๆ ซึ่งเป็นสิ่งที่for ..เกิดขึ้น

การใช้การforวนซ้ำแบบ C ปกติในกรณีส่วนใหญ่ เป็นสิ่งสำคัญที่ต้องจำไว้ว่าทุกอย่างภายในลูปจะแชร์ขอบเขตกับส่วนที่เหลือของโปรแกรมของคุณ {} จะไม่สร้างขอบเขตใหม่

ดังนั้น:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){
  sum += numbers[i];
}

alert(i);

จะส่งออก "11" - ซึ่งอาจหรืออาจจะไม่เป็นสิ่งที่คุณต้องการ

ตัวอย่าง jsFiddle ที่ใช้งานได้: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/


10

ไม่เหมือนกัน 100% แต่คล้ายกัน:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }


1
ดูเหมือนว่าสิ่งนี้จะทำงานกับปัญหาที่คล้ายกันเช่นเดียวกับอื่น ๆ ในการใช้งานกับวัตถุอาร์เรย์ในตัวแปรสมาชิกต้นแบบที่จะถูกจับโดยสำหรับในเช่นกัน
Kzqai

9

ตัวอย่างเช่นฉันใช้ในคอนโซล Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})

9
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

ทำความสะอาดมาก ...


z.forEach(j => console.log(j));ที่ไม่สะอาดมากเมื่อเทียบกับ
Sapphire_Brick

9

คำตอบสั้น ๆ : ใช่ คุณสามารถทำสิ่งนี้:

var myArray = ["element1", "element2", "element3", "element4"];

for (i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

ในคอนโซลของเบราว์เซอร์คุณสามารถเห็นสิ่งที่พิมพ์เช่น "element1", "element2" ฯลฯ


9

คุณสามารถใช้Array.prototype.forEach(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

หรือArray.prototype.map(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

หรือ jquery หรือสำหรับวิธีวนรอบที่กล่าวถึงก่อนหน้านี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.