JavaScript สำหรับ ... ในเทียบกับ


461

คุณคิดว่ามีความแตกต่างใหญ่สำหรับ ... ในและสำหรับลูปหรือไม่? คุณชอบใช้ "ทำไม" และทำไม?

สมมติว่าเรามีอาร์เรย์ที่เชื่อมโยงกัน:

var myArray = [{'key': 'value'}, {'key': 'value1'}];

ดังนั้นเราจึงสามารถย้ำ:

for (var i = 0; i < myArray.length; i++)

และ:

for (var i in myArray)

ฉันไม่เห็นความแตกต่างใหญ่ มีปัญหาเรื่องประสิทธิภาพหรือไม่


13
โปรดทราบว่าเรายังเป็นของ JS 1.6myArray.forEach(callback[, thisarg])มี:
Benji XVI

14
@Benji array.forEach เป็นจริงใน ES5
mikemaccana

2
ในการวนรอบในคุณต้องมีเงื่อนไขที่มีลักษณะเช่นนี้:if(myArray.hasOwnProperty(i)){true}
Eric Hodonsky

6
['foo', 'bar', 'baz'].forEach(function(element, index, array){ console.log(element, index, array); }); ก็โอเคที่จะใช้งานได้ทุกที่ยกเว้นใน IE8- และมันเป็นรูปแบบที่หรูหราที่สุดเท่าที่เคยมีมา
Jon z

5
นอกจากนี้ยังมีfor...ofคำสั่งในECMAScript 6เช่น:for (let i of myArray) console.log(i);
Vitalii Fedorenko

คำตอบ:


548

ตัวเลือกควรเป็นไปตามสำนวนที่เข้าใจได้ดีที่สุด

อาร์เรย์มีการทำซ้ำโดยใช้:

for (var i = 0; i < a.length; i++)
   //do stuff with a[i]

วัตถุที่ใช้เป็นอาเรย์แบบเชื่อมโยงถูกทำซ้ำโดยใช้:

for (var key in o)
  //do stuff with o[key]

หากคุณไม่มีเหตุผลที่ทำให้โลกแตกให้ยึดติดกับรูปแบบการใช้งานที่กำหนดไว้


38
ควรกล่าวถึงว่าเป็นวิธีปฏิบัติที่ดีที่จะใช้สำหรับ ... ด้วยการกรอง if statement มีวิธีการที่สะดวกของ Object "obj.hasOwnProperty (สมาชิก)" ซึ่งจะตรวจสอบว่าสมาชิกที่ส่งคืนโดย iterator เป็นสมาชิกของวัตถุหรือไม่ โปรดดู: javascript.crockford.com/code.html
Damir Zekić

57
ตามที่ได้แสดงความคิดเห็นไว้ที่คำตอบอื่นคำว่า "for ... in" จะไม่ทำงานอย่างถูกต้องสำหรับ Array เนื่องจากมันจะทำซ้ำมากกว่าคุณสมบัติและวิธีการของ Array ทั้งหมด ดังนั้นคุณควรใช้ "for ... in" เพื่อทำซ้ำคุณสมบัติของวัตถุเท่านั้น มิฉะนั้นติดที่ "สำหรับ (i = 0; i <something; i ++)"
Denilson Sá Maia

สำหรับเหตุผลด้านประสิทธิภาพ IMO จะเป็นการดีกว่าที่จะประเมินความยาวของอาเรย์ก่อนforและไม่ประเมิน a.length ทุกครั้งในลูป
UpTheCreek

9
@UpTheCreek: นั่นเป็นเรื่องจริงแน่นอนเมื่ออาเรย์นั้นมีบางสิ่งที่ HTMLDOM ส่งกลับมา แต่ฉันสงสัยว่าต้องมีจาวาสคริปต์มาตรฐานขนาดใหญ่เท่าใดก่อนที่คุณจะเห็นความแตกต่างที่เห็นได้? ส่วนตัวฉันจะเก็บรหัสให้ง่ายที่สุดเท่าที่จะทำได้จนกว่าจะพิสูจน์ได้ว่าจำเป็นต้องทำสิ่งที่แตกต่าง
AnthonyWJones

2
@Pichan ฉันคิดว่าคุณหมายถึงi < lไม่ใช่i < aในเงื่อนไข for-loop ของคุณ
Max Nanasy

161

Douglas Crockford แนะนำ JavaScript: The Good Parts (หน้า 24) เพื่อหลีกเลี่ยงการใช้for inคำสั่ง

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

ทุกอย่าง .hasOwnPropertyแต่คุณสมบัติสามารถกรองออกมาด้วย ตัวอย่างโค้ดนี้ทำในสิ่งที่คุณอาจต้องการในตอนแรก:

for (var name in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, name)) {
        // DO STUFF
    }
}

70
for ... in เหมาะสมอย่างยิ่งสำหรับการวนลูปมากกว่าคุณสมบัติของวัตถุ มันไม่เหมาะสำหรับการวนลูปมากกว่าองค์ประกอบของอาร์เรย์ หากคุณไม่เข้าใจความแตกต่างระหว่างสถานการณ์เหล่านี้คุณควรหลีกเลี่ยง ... ใน; มิฉะนั้นไปถั่ว
Shog9

8
ต้องการเน้นความจริงที่ว่ามันไม่ได้มีคำสั่ง! นี่อาจเป็นปัญหาใหญ่และเป็นข้อผิดพลาดที่ยากที่จะจับ
เจสัน

4
+1 สำหรับ "ประกอบด้วยสมาชิกที่สืบทอดมาจากเชนต้นแบบและชื่อของวิธีการ" คุณจะสนุกถ้ามีคนใช้รหัสของคุณกับโหลดต้นแบบ (แม้ว่ารหัสของคุณไม่ได้ใช้จริง) ตัวอย่าง
ijw

13
โปรดอย่าลืมที่จะประกาศnameตัวแปร: for(var name in object)...มิฉะนั้นถ้ารหัสที่อยู่ภายในฟังก์ชั่นเช่นที่nameปลายตัวแปรขึ้นเป็นทรัพย์สินของวัตถุทั่วโลก (ได้รับมอบหมายไปยังระบุไม่ได้ประกาศไม่ว่า) ยังอยู่ใน ECMAScript ใหม่ 5 ReferenceErrorเข้มงวดโหมดรหัสที่จะโยน
CMS

6
@Nosredna: มีปัญหาเกี่ยวกับคำสั่งของการทำซ้ำสำหรับ Chrome, ยื่นโดยไม่มีใครอื่นนอกจาก John Resig ที่ถูกทำเครื่องหมายเป็น WontFix code.google.com/p/chromium/issues/detail?id=883 แม้กระทั่งก่อนโครเมี่ยมลำดับของการวนซ้ำนั้นไม่เหมือนกันในเบราว์เซอร์ถ้าคุณลบแล้วเพิ่มคุณสมบัติอีกครั้ง นอกจากนี้ IE 9 ยังทำงานเหมือนโครเมี่ยม (ซึ่งคาดว่าจะปรับปรุงความเร็ว) ดังนั้น ... โปรดหยุดการแพร่กระจายข้อมูลที่ไม่ถูกต้องคุณจะไร้เดียงสามากขึ้นอยู่กับมัน
Juan Mendes

62

FYI - ผู้ใช้ jQuery


each(callback)วิธีการของ jQuery ใช้การfor( ; ; )วนซ้ำตามค่าเริ่มต้นและจะใช้for( in ) เฉพาะในกรณีที่ความยาวของมันundefinedในกรณีที่ความยาวของมัน

ดังนั้นฉันจะบอกว่ามันปลอดภัยที่จะถือว่าลำดับที่ถูกต้องเมื่อใช้ฟังก์ชั่นนี้

ตัวอย่าง :

$(['a','b','c']).each(function() {
    alert(this);
});
//Outputs "a" then "b" then "c"

ข้อเสียของการใช้สิ่งนี้คือถ้าคุณกำลังทำตรรกะที่ไม่ใช่ UI ฟังก์ชันของคุณจะไม่สามารถพกพาไปยังเฟรมเวิร์กอื่นได้น้อยลง each()ฟังก์ชั่นที่ดีที่สุดอาจจะถูกสงวนไว้สำหรับการใช้งานกับตัวเลือก jQuery และfor( ; ; )อาจจะแนะนำให้เลือกเป็นอย่างอื่น



4
มีdocumentcloud.github.com/underscoreเสมอซึ่งมี _.each และฟังก์ชั่นที่มีประโยชน์อื่น ๆ อีกมากมาย
w00t

1
หมายความว่าถ้าฉันมีคุณสมบัติความยาวในวัตถุ $ .each ของฉันจะล้มเหลว? เช่น x = {a: "1", b: "2", ความยาว: 3}
Onur Topal

29

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

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

for (var i = myArray.length-1; i >= 0; i--)

เร็วกว่าเบราว์เซอร์บางตัวเกือบสองเท่ากว่า:

for (var i = 0; i < myArray.length; i++)

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


5
การเก็บ "myArray.length" ไว้ในตัวแปรก่อนที่จะวนลูปจะทำให้ประสิทธิภาพที่แตกต่างหายไปหรือไม่ ฉันเดาว่า "ใช่"
Tomalak

3
ไม่ 'myArray.length' เป็นคุณสมบัติไม่ใช่วิธีบนวัตถุ - ไม่มีการคำนวณเพื่อกำหนดมูลค่า การเก็บค่าไว้ในตัวแปรจะไม่ทำอะไรเลย
jason

3
ใช่แล้ว คุณสมบัติไม่ใช่ตัวแปร พวกเขามีรหัสรับ / ชุด
วาง

12
ฉันมักจะใช้for(var i = myArray.length; i--;)
Kevin

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

26

โปรดทราบว่าวิธี Array.forEach ดั้งเดิมได้รับการสนับสนุนอย่างกว้างขวางแล้ว


2
มันทำอะไร? มันมีปัญหาที่กล่าวถึงในโพสต์อื่น ๆ (วนลูปมากกว่าคุณสมบัติแทนองค์ประกอบของอาร์เรย์)? นอกจากนี้เนื่องจาก IE8 ไม่รองรับจึงเป็นเรื่องที่ค่อนข้างยืดยาวที่จะกล่าวว่าได้รับการสนับสนุนอย่างกว้างขวาง
Rauni Lillemets

2
มากที่สุดเท่าที่ผู้ใช้ * ระวังดูถูกมัน IE8 เป็นส่วนใหญ่ของผู้ใช้ย่อย windows7 นั่นเป็นส่วนใหญ่ของตลาดเบราว์เซอร์
sbartell

2
@Rauni - ฉันใช้เวลาจุดของคุณ แต่สำหรับอุปกรณ์เดสก์ทอป IE ส่วนแบ่งเบราว์เซอร์คือน้อยกว่า 40% ตามen.wikipedia.org/wiki/Usage_share_of_web_browsers#Summary_tableและตามmarketshare.hitslink.com/...และเว็บไซต์อื่น ๆ อย่างน้อย 8% ของเบราว์เซอร์คือ IE 9 กล่าวอีกนัยหนึ่ง Array.forEach ได้รับการสนับสนุนโดยประมาณ 70% ของเบราว์เซอร์เดสก์ท็อปดังนั้นฉันไม่คิดว่า 'สนับสนุนอย่างกว้างขวาง' ไม่มีเหตุผล ฉันไม่ได้ตรวจสอบ แต่การรองรับมือถือ (บนเบราว์เซอร์ WebKit และ Opera) อาจสูงกว่านี้ เห็นได้ชัดว่ามีความหลากหลายทางภูมิศาสตร์
Sam Dutton

1
ขอบคุณสำหรับการอัพเดท. ฉันยอมรับว่าอาจกล่าวได้ว่าเป็น "การสนับสนุนอย่างกว้างขวาง" ปัญหาเดียวคือถ้าผู้ใช้ใช้วิธี JS นี้เขา / เธอยังคงต้องเขียนวิธีสำรองสำหรับกรณีที่ไม่ได้รับการสนับสนุน ..
Rauni Lillemets

1
@Rauni - คุณสามารถใช้ es5-shim และ es6-shim เพื่อให้วิธีการสำรองข้อมูลโดยอัตโนมัติ github.com/es-shims/es5-shim
Michiel van der Blonk

24

คำตอบที่ได้รับการอัปเดตสำหรับเบราว์เซอร์หลักทุกรุ่นในปัจจุบันปี 2555 - Chrome, Firefox, IE9, Safari และ Opera รองรับอาร์เรย์ดั้งเดิมของ ES5 สำหรับแต่ละรุ่น

นอกจากว่าคุณจะมีเหตุผลบางอย่างที่จะรองรับ IE8 โดยพื้นฐาน (โปรดจำไว้ว่า ES5-shim หรือ Chrome frame สามารถให้แก่ผู้ใช้เหล่านี้ซึ่งจะให้สภาพแวดล้อม JS ที่เหมาะสม) มันสะอาดกว่าการใช้ไวยากรณ์ที่เหมาะสมของภาษา:

myArray.forEach(function(item, index) {
    console.log(item, index);
});

เอกสารฉบับเต็มสำหรับ array.forEach () อยู่ที่ MDN


1
คุณควรจัดทำเอกสารพารามิเตอร์ของการเรียกกลับ: 1 ค่าองค์ประกอบ, 2 ดัชนีองค์ประกอบ, 3 อาร์เรย์ที่ถูกสำรวจ
drewish

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

1
@Cory: ES5 forEach สามารถเพิ่มลงในเบราว์เซอร์ ES3 รุ่นเก่าได้อย่างง่ายดาย รหัสน้อยกว่าคือรหัสที่ดีกว่า
mikemaccana

2
@ thumbnailer สามารถใช้กับอาร์เรย์และวัตถุสลับกันได้หรือไม่
hitastodestruct

1
@ hitautodestruct มันเป็นส่วนหนึ่งของต้นแบบของ Array ไม่ใช่ของ Object โดยทั่วไปในชุมชนตอนนี้ออบเจ็กต์ที่ไม่ใช่อาเรย์จะยังคงมีการทำซ้ำด้วย 'for (คีย์ var ในวัตถุ) {}'
mikemaccana

14

ทั้งสองไม่เหมือนกันเมื่ออาเรย์เบาบาง

var array = [0, 1, 2, , , 5];

for (var k in array) {
  // Not guaranteed by the language spec to iterate in order.
  alert(k);  // Outputs 0, 1, 2, 5.
  // Behavior when loop body adds to the array is unclear.
}

for (var i = 0; i < array.length; ++i) {
  // Iterates in order.
  // i is a number, not a string.
  alert(i);  // Outputs 0, 1, 2, 3, 4, 5
  // Behavior when loop body modifies array is clearer.
}

14

ใช้ forEach เพื่อข้ามโซ่ต้นแบบ

เพียงแค่ภาคผนวกสั้น ๆ ของ@ nailer คำตอบด้านบนการใช้ forEach with Object.keys หมายความว่าคุณสามารถหลีกเลี่ยงการวนซ้ำของเชนต้นแบบโดยไม่ต้องใช้ hasOwnProperty

var Base = function () {
    this.coming = "hey";
};

var Sub = function () {
    this.leaving = "bye";
};

Sub.prototype = new Base();
var tst = new Sub();

for (var i in tst) {
    console.log(tst.hasOwnProperty(i) + i + tst[i]);
}

Object.keys(tst).forEach(function (val) {
    console.log(val + tst[val]);
});

2
ไอ้นั่นลับ ๆ ล่อ ๆ มันก็คุ้มค่าที่จะอ่าน 50 โพสต์เพื่อไปที่นี้ obj = {"สีชมพู": "เป็ด", สีแดง: "ห่าน"}; Object.keys (obj) === ["pink", "red"]
Orwellophile

14

ฉันมีความคิดเห็นที่สองว่าคุณควรเลือกวิธีการทำซ้ำตามความต้องการของคุณ ฉันขอแนะนำให้คุณจริงไม่เคยห่วงผ่านพื้นเมืองArrayที่มีfor inโครงสร้าง มันเป็นวิธีที่ช้าลงและตามที่ Chase Seibert ชี้ไปที่ช่วงเวลาที่ผ่านมาไม่เข้ากันกับกรอบงานต้นแบบ

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

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

l = ''; for (m in obj) { l += m + ' => ' + obj[m] + '\n' } console.log(l);

มันทิ้งเนื้อหาของวัตถุทั้งหมด (รวมถึงเมธอดเมธอด) ไปยังบันทึก Firebug ของฉัน มีประโยชน์มาก


ลิงก์เสียแล้ว แน่นอนว่าต้องการดูเกณฑ์มาตรฐานหากมีใครมีลิงค์อื่น
Billbad

มันจะไม่แตกอีกต่อไป
Olli

Foreach วนซ้ำในต้นแบบ? เนื่องจากขณะนี้ได้รับการสนับสนุนโดยทั่วไปจึงเป็นสิ่งที่ต้นแบบควรได้รับการแก้ไข
mvrak

7

นี่คือสิ่งที่ฉันทำ

function foreach(o, f) {
 for(var i = 0; i < o.length; i++) { // simple for loop
  f(o[i], i); // execute a function and make the obj, objIndex available
 }
}

นี่คือวิธีที่คุณใช้มัน
จะทำงานในอาร์เรย์และวัตถุ (เช่นรายการองค์ประกอบ HTML)

foreach(o, function(obj, i) { // for each obj in o
  alert(obj); // obj
  alert(i); // obj index
  /*
    say if you were dealing with an html element may be you have a collection of divs
  */
  if(typeof obj == 'object') { 
   obj.style.marginLeft = '20px';
  }
});

ฉันเพิ่งทำสิ่งนี้ดังนั้นฉันจึงเปิดรับข้อเสนอแนะ :)


สิ่งที่ดี - ตรงไปตรงมาสวย!
คริส

6

ฉันจะใช้วิธีการต่าง ๆ ตามวิธีที่ฉันต้องการอ้างอิงรายการ

ใช้ foreach หากคุณต้องการรายการปัจจุบัน

ใช้สำหรับหากคุณต้องการให้ตัวทำดัชนีทำการเปรียบเทียบแบบสัมพันธ์กัน (เช่นนี้จะเปรียบเทียบกับรายการก่อนหน้า / ถัดไปได้อย่างไร)

ฉันไม่เคยสังเกตเห็นความแตกต่างของประสิทธิภาพการทำงาน ฉันรอจนกว่าจะมีปัญหาเรื่องประสิทธิภาพก่อนที่จะกังวลเกี่ยวกับเรื่องนี้


ดูคำตอบ Bnos ด้านล่าง - สำหรับ ... ในไม่ได้ทำในสิ่งที่คุณคาดหวังที่นี่และถ้าคุณใช้มันคุณก็อาจจะสนุกไปกับมัน สำหรับบันทึกต้นแบบไม่สิ่งที่ถูกต้องวิธี
marcus.greasly

4

ด้วยสำหรับ (var ฉันใน myArray)คุณสามารถห่วงมากกว่าวัตถุมากเกินไปผมจะมีชื่อที่สำคัญและคุณสามารถเข้าถึงสถานที่ให้บริการผ่านทางmyArray [ผม] นอกจากนี้วิธีการใด ๆ ที่คุณจะเพิ่มลงในวัตถุนั้นจะรวมอยู่ในลูปด้วยเช่นถ้าคุณใช้กรอบภายนอกเช่น jQuery หรือต้นแบบหรือถ้าคุณเพิ่มวิธีลงในต้นแบบของวัตถุโดยตรง ณ จุดหนึ่งฉันจะชี้ไปที่ วิธีการเหล่านั้น


4

ระวัง!

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

https://developer.mozilla.org/en/DOM/HTMLCollection

ถ้าคุณใช้คำสั่ง foreach สำหรับ (var i ใน yourList) มันจะคืนค่าการประท้วงและวิธีการของ HTMLCollection ในเบราว์เซอร์ส่วนใหญ่!

var scriptTags = document.getElementsByTagName("script");

for(var i = 0; i < scriptTags.length; i++)
alert(i); // Will print all your elements index (you can get src attribute value using scriptTags[i].attributes[0].value)

for(var i in scriptTags)
alert(i); // Will print "length", "item" and "namedItem" in addition to your elements!

แม้ว่า getElementsByTagName ควรส่งคืน NodeList แต่เบราว์เซอร์ส่วนใหญ่จะคืนค่า HTMLCollection: https://developer.mozilla.org/en/DOM/document.getElementsByTagName


3

สำหรับ in loops on Arrays เข้ากันไม่ได้กับ Prototype หากคุณคิดว่าคุณอาจจำเป็นต้องใช้ห้องสมุดดังกล่าวในอนาคตมันจะเป็นการเหมาะสมสำหรับลูป

http://www.prototypejs.org/api/array


ลืม "คุณอาจต้องใช้ห้องสมุดนั้น" คิดว่า "JS ของคุณอาจรวมอยู่กับสิ่งอื่นที่ใช้ไลบรารีนั้น" เพราะปัญหายังคงเกิดขึ้น
ijw

3

ฉันเคยเห็นปัญหาเกี่ยวกับ "สำหรับแต่ละคน" โดยใช้วัตถุและต้นแบบและอาร์เรย์

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


3

หากคุณต้องการเพิ่มความเร็วรหัสของคุณจริง ๆ แล้วล่ะ

for( var i=0,j=null; j=array[i++]; foo(j) );

มันค่อนข้างมีตรรกะแบบ while ในคำสั่ง for และซ้ำซ้อนน้อยลง นอกจากนี้ firefox ยังมี Array.forEach และ Array.filter


2
ทำไมรหัสของคุณถึงเร็วขึ้น? ฉันไม่เห็นว่าทำไมข้อความการอ้างถึงเช่นนี้จะทำให้เร็วขึ้น
รูปี

3

รหัสที่สั้นและดีที่สุดตาม jsperf คือ

keys  = Object.keys(obj);
for (var i = keys.length; i--;){
   value = obj[keys[i]];// or other action
}

1

ใช้ Array () สำหรับ forEach loop เพื่อใช้ประโยชน์จากการขนาน


4
JavaScript ในเบราว์เซอร์เป็นลูปเหตุการณ์พร้อมกันดังนั้นArray.prototype.forEachจะไม่ดำเนินการเรียกหลายครั้งไปยังการโทรกลับพร้อมกัน
Mike Samuel


0

ระวัง!!! ฉันใช้ Chrome 22.0 ใน Mac OS และฉันมีปัญหากับแต่ละไวยากรณ์

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

var MyTest = {
    a:string = "a",
    b:string = "b"
};

myfunction = function(dicts) {
    for (var dict in dicts) {
        alert(dict);
        alert(typeof dict); // print 'string' (incorrect)
    }

    for (var i = 0; i < dicts.length; i++) {
        alert(dicts[i]);
        alert(typeof dicts[i]); // print 'object' (correct, it must be {abc: "xyz"})
    }
};

MyObj = function() {
    this.aaa = function() {
        myfunction([MyTest]);
    };
};
new MyObj().aaa(); // This does not work

myfunction([MyTest]); // This works

0

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

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

//Output
0
1

for (var i in myArray) { 
    console.log(i) 
} 

// Output
0 
1 
remove

if(myArray.hasOwnProperty(i))คุณสามารถใช้สำหรับในที่มี ยังคงเมื่อทำซ้ำมากกว่าอาร์เรย์ฉันชอบที่จะหลีกเลี่ยงปัญหานี้และเพียงแค่ใช้คำสั่ง for (;;)


0

แม้ว่าพวกเขาทั้งสองเหมือนกันมากมีความแตกต่างเล็กน้อย:

var array = ["a", "b", "c"];
array["abc"] = 123;
console.log("Standard for loop:");
for (var index = 0; index < array.length; index++)
{
  console.log(" array[" + index + "] = " + array[index]); //Standard for loop
}

ในกรณีนี้ผลลัพธ์คือ:

มาตรฐานสำหรับลูป:

ARRAY [0] = A

ARRAY [1] = B

ARRAY [2] = C

console.log("For-in loop:");
for (var key in array)
{
  console.log(" array[" + key + "] = " + array[key]); //For-in loop output
}

ในขณะที่ในกรณีนี้ผลลัพธ์คือ:

FOR-IN LOOP:

ARRAY [1] = B

ARRAY [2] = C

ARRAY [10] = D

ARRAY [ABC] = 123


0

คำสั่ง for in อนุญาตให้วนลูปผ่านชื่อของคุณสมบัติทั้งหมดของวัตถุ น่าเสียดายที่มันยังวนซ้ำผ่านสมาชิกทั้งหมดที่สืบทอดผ่านห่วงโซ่ต้นแบบ สิ่งนี้มีผลข้างเคียงที่ไม่ดีในการใช้งานฟังก์ชันเมธอดเมื่อความสนใจอยู่ในข้อมูลสมาชิก

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