javascript - لغة - شرح جافا سكريبت




لكل من خلال مجموعة في جافا سكريبت؟ (19)

عروة للخلف

أعتقد أن العكس للحلقة يستحق الذكر هنا:

for (var i = array.length; i--; ) {
     // process array[i]
}

مزايا:

  • لا تحتاج إلى إعلان متغير len مؤقت ، أو مقارنة ضد array.length في كل تكرار ، قد يكون أي منهما array.length .
  • إزالة الأشقاء من DOM بترتيب عكسي عادة ما تكون أكثر كفاءة . (يحتاج المتصفح إلى تقليل نقل العناصر في صفائفه الداخلية.)
  • إذا قمت بتعديل المصفوفة أثناء التكرار ، أو عند الفهرس i (على سبيل المثال قمت بإزالة عنصر أو إدراجه في array[i] ) ، فستتخطى حلقة أمامية العنصر الذي تحول إلى اليسار في الموضع i ، أو تعيد معالجة i. البند عشر الذي تم نقله الحق. في حلقة تقليدية ، يمكنك تحديث i للإشارة إلى العنصر التالي الذي يحتاج إلى معالجة - 1 ، ولكن ببساطة عكس اتجاه التكرار هو غالباً حل أبسط وأنيق .
  • وبالمثل ، عند تعديل عناصر DOM المتداخلة أو إزالتها ، يمكن للمعالجة في الاتجاه المعاكس التحايل على الأخطاء . على سبيل المثال ، فكر في تعديل innerHTML لعقدة رئيسية قبل التعامل مع الأطفال. في الوقت الذي يتم فيه الوصول إلى العقدة الفرعية ، سيتم فصله عن DOM ، بعد أن تم استبداله بطفل تم إنشاؤه حديثًا عندما تم كتابة لغة HTML الداخلية.
  • من الأقصر الكتابة والقراءة أكثر من بعض الخيارات الأخرى المتاحة. على الرغم من أنه يخسر ل forEach() و ES6 ل for ... of .

سلبيات:

  • يقوم بمعالجة العناصر بترتيب عكسي. إذا كنت تقوم ببناء مصفوفة جديدة من النتائج ، أو طباعة أشياء على الشاشة ، فسيتم عكس الناتج بشكل طبيعي فيما يتعلق بالترتيب الأصلي.
  • يعد إدراج الأشقاء بشكل متكرر في DOM كطفل أول من أجل الاحتفاظ بأمرهم أقل كفاءة . (سيبقى المتصفح مضطرًا إلى تغيير الأمور بشكل صحيح.) لإنشاء عقد DOM بطريقة فعّالة وفي ترتيب ، ما عليك سوى إعادة توجيه الزوايا وإلحاقها كالمعتاد (وأيضًا استخدام "جزء المستند").
  • حلقة عكسي مربكة للمطورين المبتدئين. (قد تفكر في هذه الميزة ، اعتمادا على نظرتك.)

هل يجب علي دائمًا استخدامها؟

يستخدم بعض المطورين العكسي للحلقة افتراضيًا ، ما لم يكن هناك سبب وجيه لإجراء تكرار للأمام.

على الرغم من أن مكاسب الأداء عادةً ما تكون غير ذات أهمية ، إلا أنها نوع من الصراخ:

"فقط افعل ذلك لكل عنصر في القائمة ، لا يهمني الأمر!"

ومع ذلك ، لا يعد ذلك في الواقع إشارة موثوقة على النية ، نظرًا لأنه لا يمكن تمييزه عن تلك المناسبات عندما تهتم بالأمر ، وتحتاج حقًا إلى الرجوع إلى الخلف. في الواقع ، ستكون هناك حاجة لبنية أخرى للتعبير بدقة عن نية "لا يهمني" ، وهو أمر غير متوفر حاليًا في معظم اللغات ، بما في ذلك ECMAScript ، ولكن يمكن استدعاؤه ، على سبيل المثال ، forEachUnordered() .

إذا لم يكن الأمر مهمًا ، وكانت الكفاءة مصدر قلق (في الحلقة الداخلية لمحرك ألعاب أو حركة متحركة) ، فقد يكون من المقبول استخدام الرجوع للخلف كنمط الانتقال. فقط تذكر أن رؤية عكس للحلقة في الكود الحالي لا يعني بالضرورة أن الأمر غير ذي صلة!

من الأفضل استخدام forEach ()

بوجه عام ، بالنسبة إلى الشفرة ذات المستوى الأعلى حيث تُعد درجة الوضوح والسلامة من المخاوف الأكبر ، فإنني Array::forEach باستخدام Array::forEach الافتراضي:

  • من الواضح أن تقرأ.
  • يشير هذا إلى أنه لن يتم تحويلي داخل الكتلة (وهو دائمًا ما يمثل مفاجأة محتملة مختبئة في حلقات طويلة while .)
  • يمنحك نطاقًا مجانيًا للإغلاق.
  • فهو يقلل من تسرب المتغيرات المحلية والتصادم العرضي مع المتغيرات الخارجية (والطفرات).

بعد ذلك ، عندما ترى عكس الحل في الشفرة ، فهذا تلميح إلى أنه يتم عكسه لسبب وجيه (ربما أحد الأسباب الموضحة أعلاه). ورؤية التتابع التقليدي للحلقة قد يشير إلى أن التحول قد يحدث.

(إذا لم تكن مناقشة النوايا منطقية بالنسبة لك ، فقد تستفيد أنت ورمزك من مشاهدة محاضرة كروكفورد حول أسلوب البرمجة ودماغك .)

كيف يعمل؟

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

ستلاحظ أن i-- هي العبارة المتوسطة (حيث نرى عادة المقارنة) وأن الجملة الأخيرة فارغة (حيث نرى عادة i++ ). وهذا يعني أن i-- تستخدم أيضًا كشرط للاستمرار. بشكل حاسم ، يتم تنفيذه وفحصه قبل كل تكرار.

  • كيف يمكن أن تبدأ في array.length دون انفجار؟

    نظرًا لأن i-- يعمل قبل كل عملية تكرار ، ففي أول عملية تكرار ، سنتمكن بالفعل من الوصول إلى العنصر في array.length - 1 الذي يتجنب أي مشكلات تتعلق array.length - 1 خارج النطاق undefined .

  • لماذا لا يتوقف عن التكرار قبل الفهرس 0؟

    ستتوقف الحلقة عن التكرار عند تقييم الحالة i-- إلى قيمة falsey (عندما تعطي 0).

    الخدعة هي أنه على عكس - --i ، يتتبع مشغل i trailing i ولكنه يعطي القيمة قبل الانخفاض. يمكن أن توضح وحدة التحكم الخاصة بك هذا:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    إذن في التكرار النهائي ، كنت في السابق 1 والتعبير i-- يغيره إلى 0 ولكنه في الواقع ينتج 1 (صحيح) ، وهكذا تمر الحالة. في التكرار التالي i - يتغير i إلى -1 ولكن ينتج 0 (falsey) ، مما يؤدي إلى تنفيذ التنفيذ على الفور من أسفل الحلقة.

    في العقود التقليدية للحلقة ، i++ و ++i قابلة للتبادل (كما يشير دوغلاس كروكفورد). ولكن في الاتجاه المعاكس للحلقة ، لأن تناقصنا هو أيضًا تعبير الحالة الخاص بنا ، يجب علينا الالتزام بـ i-- إذا أردنا معالجة العنصر في index 0.

توافه

يحب بعض الأشخاص رسم سهم صغير في الاتجاه المعاكس للحلقة ، وينتهي بغمزة:

for (var i = array.length; i --> 0 ;) {

تذهب الاعتمادات إلى WYL لتعرض لي فوائد وأهوال العكس للحلقة.

كيف يمكنني تكرار جميع الإدخالات في صفيف باستخدام JavaScript؟

اعتقدت انه شيء من هذا القبيل:

forEach(instance in theArray)

أين هو theArray ، ولكن يبدو أن هذا غير صحيح.


ملخص:

عند التكرار على صفيف ، غالبًا ما نرغب في تحقيق أحد الأهداف التالية:

  1. نريد التكرار عبر الصفيف وإنشاء مصفوفة جديدة:

    Array.prototype.map

  2. نريد التكرار أكثر من المصفوفة ولا ننشئ مصفوفة جديدة:

    Array.prototype.forEach

    for..of عقدة

في JS هناك العديد من الطرق لتحقيق كل من هذه الأهداف. ومع ذلك ، فإن بعضها أكثر رحابة من غيرها. فيما يلي يمكنك العثور على بعض الطرق الشائعة الاستخدام (أكثر imo conventient) لإنجاز تكرار الصفيف في javascript.

خلق مجموعة جديدة: Map

map()هي وظيفة تقع على Array.prototypeأي منها يمكن تحويل كل عنصر من صفيف ثم إرجاع صفيف جديد . map()يأخذ كحجة وظيفة رد اتصال ويعمل بالطريقة التالية:

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

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

يتم تنفيذ رد الاتصال الذي تم تمريره map()إليه كحجة لكل عنصر. ثم يتم إرجاع صفيف له نفس طول الصفيف الأصلي. يتم تحويل عنصر الصفيف الجديد هذا بواسطة وظيفة رد الاتصال التي تم تمريرها كوسيطة لـ map().

الاختلاف المتميز بين mapو آلية الحلقة الأخرى مثل forEachو for..ofالحلقة هي تلك mapالعوائد كمصفوفة جديدة و تترك المجموعة القديمة سليمة (إلا إذا كنت تتعامل مع التفسير مع التفكير splice).

لاحظ أيضًا أن mapمعاودة الاتصال للدالة توفر كوسيطة ثانية رقم الفهرس للتكرار الحالي. علاوة على ذلك ، توفر الوسيطة الثالثة المصفوفة التي mapتم استدعاؤها. في بعض الأحيان يمكن أن تكون هذه الخصائص مفيدة للغاية.

حلقة باستخدام forEach

forEachهي وظيفة تقع على Array.prototypeوالتي تأخذ وظيفة رد اتصال كوسيطة. ومن ثم ينفذ وظيفة رد الاتصال هذه لكل عنصر في الصفيف. على النقيض من map()الوظيفة الدالة forEach بإرجاع لا شيء ( undefined). فمثلا:

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

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

تمامًا مثل mapالدالة ، forEachيوفر رد الاتصال كوسيطة ثانية رقم الفهرس للتكرار الحالي. كما توفر الوسيطة الثالثة المصفوفة التي forEachتم استدعاؤها.

التكرار من خلال العناصر باستخدام for..of

في for..ofحلقة الحلقات من خلال كل عنصر من عناصر مجموعة (أو أي كائن iterable الأخرى). يعمل بالطريقة التالية:

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

for(let element of arr) {
  console.log(element * 2);
}

في المثال أعلاه elementيرمز لعنصر arrالصفيف وهو المصفوفة التي نريد تكرارها. لا يعني أن الاسم elementتعسفي وكان من الممكن أن نختار أي اسم آخر مثل '' el '' أو شيء أكثر إعلانًا عندما يكون ذلك قابلاً للتطبيق.

لا تخلط بين for..inالحلقة for..ofوالحلقة. for..inسوف يتكرر من خلال جميع الخصائص التي لا تعد ولا تحصى من الصفيف ، في حين أن for..ofالحلقة ستعمل فقط على التكرار خلال عناصر الصفيف. فمثلا:

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

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}


إذا كنت تستخدم مكتبة jQuery ، فيمكنك استخدام jQuery.each :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

تصحيح :

وفقًا للسؤال ، يريد المستخدم رمزًا في javascript بدلاً من jquery حتى يكون التعديل

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

تستخدم بعض لغات C -style foreach خلال التعدادات. في جافا سكريبت يتم ذلك باستخدام بنية الحلقة في :

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

هناك الصيد. for..in سوف حلقة من خلال كل من أعضاء الكائن لا تعد ولا تحصى ، وأعضاء على النموذج الأولي لها. لتجنب قراءة القيم الموروثة من خلال النموذج الأولي للكائن ، ما عليك سوى التحقق مما إذا كان الموقع ينتمي إلى الكائن:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

بالإضافة إلى ذلك ، قام ECMAScript 5 بإضافة طريقة forEach إلى Array.prototype والتي يمكن استخدامها في التعداد عبر مصفوفة باستخدام calback (يوجد polyfill في المستندات حتى تتمكن من الاستمرار في استخدامه للمتصفحات القديمة):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

من المهم ملاحظة أن Array.prototype.forEach لا تنكسر عند إرجاع الاستدعاء false . jQuery و Underscore.js الخاصة each لتوفير حلقات يمكن أن تكون قصيرة الدارة.


TL، DR

  • لا تستخدمها إلا إذا كنت تستخدمها مع ضمانات أو على الأقل تدرك لماذا قد يعضك.
  • افضل رهاناتك هي عادة

    • حلقة for-of (ES2015 + فقط) ،
    • Array#forEach ( spec | MDN ) (أو أقاربها some هذا القبيل) (ES5 + فقط) ،
    • بسيطة قديمة للحلقة ،
    • أو مع الضمانات.

ولكن هناك الكثير لاستكشافه ، اقرأ ...

جافا سكريبت لديه دلالات قوية لصفحات من خلال المصفوفات وكائنات مثل مجموعة. لقد قسمت الإجابة إلى جزئين: خيارات للصفائف الأصلية ، وخيارات للأشياء التي تشبه المصفوفة فقط ، مثل كائن arguments ، كائنات أخرى قابلة للتكرار (ES2015 +) ، ومجموعات DOM ، وما إلى ذلك.

سألاحظ بسرعة أنه يمكنك استخدام خيارات ES2015 الآن ، حتى على محركات ES5 ، عن طريق تحويل ES2015 إلى ES5. البحث عن "ES2015 transpiling" / "ES6 transpiling" للمزيد ...

حسنًا ، دعنا ننظر إلى خياراتنا:

لصفائف الفعلية

لديك ثلاثة خيارات في ECMAScript 5 ("ES5") ، الإصدار المدعوم بشكل واسع في الوقت الحالي ، واثنين إضافيين إضافيين في ECMAScript 2015 ("ES2015" ، "ES6"):

  1. استخدم forEach وذات صلة (ES5 +)
  2. استخدم بسيطة للحلقة
  3. استخدم for-in بشكل صحيح
  4. استخدام for-of (استخدام المكرّر ضمنيًا) (ES2015 +)
  5. استخدم مكررًا واضحًا (ES2015 +)

تفاصيل:

1. استخدم forEach وذات الصلة

في أي بيئة مبهمة حديثة (لذا ، لا IE8) حيث يمكنك الوصول إلى ميزات Array التي أضافها ES5 (مباشرة أو باستخدام polyfills) ، يمكنك استخدام forEach ( spec | MDN ):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach يقبل وظيفة رد اتصال و ، اختياريًا ، قيمة لاستخدامها this عند استدعاء ذلك رد الاتصال (غير مستخدمة أعلاه). يتم استدعاء رد الاتصال لكل إدخال في الصفيف ، بالترتيب ، تخطي الإدخالات غير الموجودة في المصفوفات المتفرقة. على الرغم من أنني لا أستخدم سوى وسيطة واحدة فقط ، إلا أنه يتم استدعاء معاودة الاتصال بثلاثة: قيمة كل إدخال ، وفهرسة هذا الإدخال ، وإشارة إلى المصفوفة التي تقوم بتكرارها (في حال لم تكن وظيفتك متوفرة بالفعل) ).

ما لم تكن متصفحات قديمة مثل IE8 (والتي تعرضها NetApps بحصة سوقية تزيد عن 4٪ حتى وقت كتابة هذا التقرير في سبتمبر 2016) ، يمكنك استخدام كلمة forEach في صفحة ويب ذات أغراض عامة بدون رقاقة. إذا كنت بحاجة إلى دعم المتصفحات القديمة ، forEach بسهولة القيام forEach shimming / forEach (البحث عن "es5 shim" للعديد من الخيارات).

لدى forEach ميزة لا تضطر إلى forEach عن متغيرات الفهرسة والقيمة في نطاق forEach حيث يتم forEach التكرار ، ومن ثم يتم تحديد نطاقها بدقة إلى هذا التكرار فقط.

إذا كنت قلقًا بشأن تكلفة وقت التشغيل لإجراء مكالمة دالة لكل إدخال صفيف ، فلا تقلق ؛ blog.niftysnippets.org/2012/02/foreach-and-runtime-cost.html .

بالإضافة إلى ذلك ، forEach هي forEach "حلقة من خلال جميع" ، ولكن ES5 حدد العديد من الوظائف المفيدة الأخرى "طريقك من خلال وظائف المصفوفة والأشياء" ، بما في ذلك:

  • every (يتوقف عن التكرار في المرة الأولى التي تظهر فيها معاودة الاتصال false أو false ما)
  • some (يتوقف عن التكرار في المرة الأولى التي يرجع فيها رد الاتصال true أو شيئًا صائبًا)
  • filter (ينشئ صفيفًا جديدًا يتضمن عناصر حيث تقوم وظيفة التصفية بإرجاع true وإهمالها حيث تقوم بإرجاع false )
  • map (إنشاء صفيف جديد من القيم التي يتم إرجاعها بواسطة معاودة الاتصال)
  • reduce (إنشاء قيمة عن طريق استدعاء معاودة الاتصال بشكل متكرر ، تمرير القيم السابقة ؛ راجع المواصفات للحصول على التفاصيل ؛ مفيدة لتلخيص محتويات صفيف والعديد من الأشياء الأخرى)
  • reduceRight (مثل reduce ، ولكنه يعمل بترتيب تنازلي بدلاً من ترتيب تصاعدي)

2. استخدم بسيطة للحلقة

في بعض الأحيان تكون الطرق القديمة هي الأفضل:

var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}

إذا لم يتغير طول المصفوفة خلال الحلقة ، وكان في رمز حساس للأداء (غير محتمل) ، قد تكون نسخة أكثر تعقيدًا قليلاً تشد الطول إلى الأمام أسرع قليلاً:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}

و / أو العد إلى الخلف:

var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

ولكن مع محركات جافا سكريبت الحديثة ، من النادر أن تحتاج إلى آخر قطعة من العصير.

في ES2015 والإصدارات الأحدث ، يمكنك جعل متغيرات الفهرس والقيمة المحلية محلية للحلقة:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

وعندما تفعل ذلك ، ليس فقط value ولكن يتم إعادة إنشاء index أيضًا لكل تكرار حلقة ، بمعنى أن عمليات الإغلاق التي تم إنشاؤها في هيئة الحلقات تحتفظ بإشارة إلى index ( value ) التي تم إنشاؤها لهذا التكرار المحدد:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

إذا كان لديك خمسة divs ، فستحصل على "Index is: 0" إذا قمت بالنقر فوق "First" و "Index is: 4" إذا قمت بالنقر فوق الأخير. هذا لا يعمل إذا كنت تستخدم var بدلاً من let .

3. استخدم for-in بشكل صحيح

ستجعل الأشخاص يخبرونك بأنك تستخدم for-in ، ولكن هذا ليس ما تريده . حلقات for-in خلال الخصائص التي لا تعد ولا تحصى لكائن ، وليس فهارس صفيف. لم يتم ضمان الطلب ، حتى في ES2015 (ES6). يحدد ES2015 ترتيبًا لخصائص الكائن (عبر [[OwnPropertyKeys]] ، [[Enumerate]] ، والأشياء التي تستخدمها مثل Object.getOwnPropertyKeys ) ، لكنه لا يحدد أن for-in سوف يتبع ذلك الترتيب. (التفاصيل في هذه الإجابة الأخرى .)

ومع ذلك ، يمكن أن يكون مفيدًا ، خاصة بالنسبة للمصفوفات المتفرقة ، إذا استخدمت ضمانات مناسبة:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

لاحظ الشيكات اثنين:

  1. أن الكائن له خاصية خاصة به بهذا الاسم (وليس من حيث أنه يرث من النموذج الأولي) ، و

  2. أن المفتاح عبارة عن سلسلة رقمية 10 الأساسية في نموذج السلسلة العادي الخاص به وقيمته هي <= 2 ^ 32 - 2 (وهو 4،294،967،294). من أين يأتي هذا الرقم؟ إنه جزء من تعريف فهرس الصفيف في المواصفات . الأرقام الأخرى (غير الأعداد الصحيحة ، والأرقام السالبة ، والأرقام الأكبر من 2 ^ 32 - 2) ليست من فهارس المصفوفات. والسبب في ذلك هو 2 ^ 32 - 2 هو أن ذلك يجعل قيمة أكبر مؤشر واحد أقل من 2 ^ 32 - 1 ، وهي القيمة القصوى التي يمكن أن يكون لها length الصفيف. (على سبيل المثال ، يناسب طول الصفيف في عدد صحيح 32 بت بدون إشارة .) (الدعائم إلى RobG للإشارة في تعليق على نشر مدونتي بأن الاختبار السابق لم يكن صحيحًا تمامًا))

هذه عبارة عن جزء صغير من التحميل الزائد لكل تكرار حلقة في معظم المصفوفات ، ولكن إذا كان لديك صف متناثر ، فيمكن أن تكون طريقة أكثر فاعلية للحلقة لأنها تعمل فقط على إدخالات موجودة بالفعل. على سبيل المثال ، بالنسبة للمصفوفة أعلاه ، نقوم بتكرار ما مجموعه ثلاث مرات (للمفاتيح "0" و "10" و "10000" - تذكر ، إنها سلاسل) ، وليس 10001 مرة.

الآن ، لن ترغب في الكتابة في كل مرة ، لذلك يمكنك وضع هذا في مجموعة الأدوات الخاصة بك:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}

ثم نستخدمها على هذا النحو:

for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

أو إذا كنت مهتمًا باختبار "جيد بما فيه الكفاية لمعظم الحالات" ، فيمكنك استخدام هذا ، لكن في حين أنه قريب ، فهو ليس صحيحًا تمامًا:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

4. استخدام for-of (استخدام itator ضمني) (ES2015 +)

يضيف ES2015 المثيرات إلى جافا سكريبت. أسهل طريقة لاستخدام المكررة هي عبارة for-of العبارة الجديدة. تبدو هكذا:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

انتاج:

a
b
c

تحت الأغطية ، الذي يحصل على مكرر من الصفيف وحلقات من خلاله ، والحصول على القيم منه. هذا ليس لديه مشكلة في استخدام for-in ، لأنه يستخدم أداة مساعدة محددة بواسطة الكائن (المصفوفة) ، و المصفوفات تحدد أن المتكررات تقوم بالتكرار من خلال إدخالاتها (وليس خصائصها). على عكس for-in in ES5 ، الترتيب الذي تتم فيه زيارة المقالات هو الترتيب الرقمي لفهارسها.

5. استخدم مكررًا واضحًا (ES2015 +)

في بعض الأحيان ، قد ترغب في استخدام مكرر بشكل صريح . يمكنك القيام بذلك أيضا ، على الرغم من أنه كثير clunkier من for-of . تبدو هكذا:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

المكرر هو كائن مطابق لتعريف Iterator في المواصفات. ترجع الطريقة next لكائن نتيجة جديد في كل مرة تتصل بها. يحتوي كائن النتيجة على خاصية ، done ، تخبرنا ما إذا كان يتم ذلك ، value خاصية لها قيمة ذلك التكرار. (يكون اختياريًا إذا كان false ، تكون value اختيارية إذا كان undefined .)

يختلف معنى value باختلاف المكرر ؛ دعم المصفوفات (على الأقل) ثلاث وظائف تعيد التكرار:

  • values() : هذا هو الذي استخدمته أعلاه. تقوم بإرجاع مكرر حيث تكون كل value إدخال الصفيف لهذا التكرار ( "a" و "b" و "c" في المثال السابق).
  • keys() : إرجاع مكرر حيث تكون كل value هي المفتاح لذلك التكرار (لذلك بالنسبة a سبق ، سيكون ذلك هو "0" ، ثم "1" ، ثم "2" ).
  • entries() : إرجاع مكرر حيث تكون كل value صفيف في النموذج [key, value] لذلك التكرار.

من أجل كائنات تشبه صفيف

وبصرف النظر عن المصفوفات الحقيقية ، هناك أيضا كائنات شبيهة بالمصفوفة التي لها خاصية length وخصائص ذات أسماء رقمية: مثيلات NodeList ، كائن الـ arguments ، إلخ. كيف NodeList محتوياتها؟

استخدم أيًا من الخيارات المذكورة أعلاه للصفائف

على الأقل بعض ، وربما معظم أو حتى كل ، من النهج الصفيف أعلاه تطبق بشكل متساو بشكل جيد على كائنات مثل مجموعة:

  1. استخدم forEach وذات صلة (ES5 +)

    وظائف مختلفة على Array.prototype هي "عامة عمدا" ويمكن استخدامها عادة على كائنات شبيهة بالمصفوفة عن طريق Function#call Function#apply أو Function#apply . (راجع " التحذير" للكائنات المقدمة بواسطة المضيف في نهاية هذه الإجابة ، ولكنها مشكلة نادرة.)

    افترض أنك تريد استخدام forEach على forEach Node . سوف تفعل هذا:

    Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    

    إذا كنت ستفعل ذلك كثيرًا ، فقد ترغب في الحصول على نسخة من مرجع الدالة في متغير لإعادة الاستخدام ، على سبيل المثال:

    // (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    
  2. استخدم بسيطة للحلقة

    من الواضح أن حلقة بسيطة للتطبيق تنطبق على كائنات تشبه المصفوفة.

  3. استخدم for-in بشكل صحيح

    for-in مع نفس الضمانات كما هو الحال مع مصفوفة يجب أن تعمل مع كائنات شبيهة بالمصفوفة كذلك ؛ قد يتم تطبيق التحذير الخاص بالكائنات المقدمة من المضيف على # 1 أعلاه.

  4. استخدام for-of (استخدام المكرّر ضمنيًا) (ES2015 +)

    for-of will use the iterator provided by the object (if any)؛ سيكون علينا أن نرى كيف يلعب هذا مع الأجسام الشبيهة بالمصفوفة ، وخاصة تلك التي يقدمها المضيف. على سبيل المثال ، تم تحديث مواصفات NodeList من querySelectorAll لدعم التكرار. لم تكن مواصفات HTMLCollection من HTMLCollection .

  5. استخدم مكررًا واضحًا (ES2015 +)

    انظر رقم 4 ، سيتعين علينا رؤية كيفية تشغيل المكرّرين.

إنشاء مجموعة حقيقية

في أحيان أخرى ، قد ترغب في تحويل كائن شبيه بالمصفوفة إلى مصفوفة حقيقية. القيام بذلك أمر سهل للغاية:

  1. استخدم طريقة slice المصفوفات

    يمكننا استخدام طريقة slice المصفوفات ، والتي مثلها مثل الطرق الأخرى المذكورة أعلاه هي "عامة عمداً" ويمكن استخدامها مع كائنات شبيهة بالمصفوفة ، مثل:

    var trueArray = Array.prototype.slice.call(arrayLikeObject);
    

    على سبيل المثال ، إذا أردنا تحويل NodeList إلى مصفوفة حقيقية ، فيمكننا إجراء ذلك:

    var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
    

    انظر التحذير للكائنات المقدمة من المضيف أدناه. على وجه الخصوص ، لاحظ أن هذا سوف يفشل في IE8 والإصدارات السابقة ، والتي لا تسمح لك باستخدام الكائنات المقدمة بواسطة المضيف مثل هذا.

  2. استخدم صيغة الانتشار ( ... )

    من الممكن أيضًا استخدام بنية انتشار ES2015 مع محركات جافا سكريبت التي تدعم هذه الميزة:

    var trueArray = [...iterableObject];
    

    لذلك ، على سبيل المثال ، إذا أردنا تحويل NodeList إلى مصفوفة حقيقية ، فإن صيغة الانتشار هذه تصبح مقتضبة تمامًا:

    var divs = [...document.querySelectorAll("div")];
    
  3. استخدم Array.from (spec) | (MDN)

    Array.from (ES2015 + ، ولكن بسهولة polyfilled) بإنشاء مصفوفة من كائن شبيه بالصفيف ، بشكل اختياري تمرير الإدخالات من خلال وظيفة التعيين أولاً. وبالتالي:

    var divs = Array.from(document.querySelectorAll("div"));
    

    أو إذا كنت ترغب في الحصول على مجموعة من أسماء العلامات للعناصر مع فئة معينة ، فستستخدم وظيفة التعيين:

    // Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });
    

التحفيز على الكائنات المقدمة من المضيف

إذا كنت تستخدم وظائف Array.prototype مع كائنات شبيهة بالمصفوفة المقدمة من المضيف (قوائم DOM وأشياء أخرى يوفرها المتصفح بدلاً من محرك جافا سكريبت) ، فيجب التأكد من اختبار البيئات المستهدفة للتأكد من توفير المضيف كائن يتصرف بشكل صحيح. معظمهم يتصرف بشكل صحيح (الآن) ، ولكن من المهم اختباره. السبب في ذلك هو أن معظم أساليب Array.prototype التي من المحتمل أن ترغب في استخدامها تعتمد على الكائن المقدم من المضيف لإعطاء إجابة صادقة على العملية [[HasProperty]] المجردة. حتى كتابة هذه السطور ، فإن المتصفحات تقوم بعمل جيد جدًا ، إلا أن مواصفات 5.1 قد سمحت بإمكانية ألا يكون الكائن الذي قدمته المضيف صريحًا. في الفقرة §8.6.2 ، عدة فقرات أسفل الجدول الكبير بالقرب من بداية هذا القسم) ، حيث تقول:

قد تقوم الكائنات المضيفة بتطبيق هذه الطرق الداخلية بأي طريقة ما لم يتم تحديدها بخلاف ذلك ؛ على سبيل المثال ، أحد الاحتمالات هو أن [[Get]] و [[Put]] لكائن مضيف معين يجلب ويخزن قيم الخصائص ولكن دائما [[HasProperty]] يولد خطأ .

(لم أتمكن من العثور على الإسهاب المكافئ في مواصفات ES2015 ، ولكن لا بد أن تكون الحالة كذلك.) مرة أخرى ، اعتبارًا من كتابة هذه السطور ، الكائنات شبيهة بالمصفوفة التي تقدمها NodeList في المتصفحات الحديثة [ NodeList ، على سبيل المثال] معالجة [[HasProperty]] بشكل صحيح ، ولكن من المهم اختبارها.)


اعتبارا من ES6:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

حيث ofيتجنب الشذوذ المرتبط به inويجعله يعمل مثل forحلقة أي لغة أخرى ، letويربط iداخل الحلقة بدلاً من داخل الوظيفة.

{}يمكن حذف الأقواس ( ) عند وجود أمر واحد فقط (على سبيل المثال في المثال أعلاه).


عن طريق حلقات مع ES6 destructuring و مشغل انتشار

لقد أثبتت عملية التدمير واستخدام مشغِّل النشر فائدة كبيرة للقادمين الجدد إلى ES6 على أنها أكثر قابلية للقراءة / الجمالية ، على الرغم من أن بعض قدامى المحاربين في جافا سكريبت قد يعتبرونها فوضويًا أو صغارًا أو قد يجدها البعض الآخر مفيدة.

سوف تستخدم الأمثلة التالية for...ofالعبارة .forEachوالطريقة.

يمكن استخدام الأمثلة 6 و 7 و 8 مع أي حلقات وظيفية مثل .map، .filter، .reduce، .sort، .every، .some، لمزيد من المعلومات حول هذه الطرق تحقق من كائن الصفيف .

مثال 1:for...of حلقة عادية - لا توجد حيل هنا.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

مثال 2: تقسيم الكلمات إلى أحرف

let arrFruits = ['apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);

}

المثال 3: التكرار مع keyوvalue

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type: 
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

مثال 4: الحصول على خصائص الكائن مضمنة

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

مثال 5: احصل على خصائص الكائن العميق لما تحتاجه

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

المثال 6: هل المثال 3 مستخدم مع.forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

المثال 7: هل المثال 4 مستخدم مع.forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions 
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

مثال 8: هل المثال 5 مستخدم مع.forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});


ECMAScript5 (الإصدار الموجود على Javascript) للعمل مع صفائف.

forEach - يتكرر من خلال كل عنصر في الصفيف وتفعل كل ما تحتاجه مع كل عنصر.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

في حالة ، أكثر اهتماما بالعملية على صفيف باستخدام بعض ميزة يحمل في ثناياه عوامل.

map - يقوم بإنشاء مصفوفة جديدة مع نتيجة وظيفة رد الاتصال. هذه الطريقة جيدة لاستخدامها عندما تحتاج إلى تنسيق عناصر المصفوفة الخاصة بك.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

اختزال - كما يقول الاسم ، فإنه يقلل من الصفيف إلى قيمة واحدة عن طريق استدعاء وظيفة معينة تمر في عنصر currenct ونتيجة للتنفيذ السابق.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - إرجاع true أو false إذا اجتازت جميع العناصر في الصفيف الاختبار في وظيفة رد الاتصال.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

مرشح - تشبه إلى حد كبير كل ما عدا ذلك المرشح بإرجاع مصفوفة مع العناصر التي ترجع صحتها إلى وظيفة معينة.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

اتمني ان يكون ذلك مفيدا.


إذا كنت لا تمانع في إفراغ الصفيف:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

xسيحتوي على القيمة الأخيرة yوسيتم إزالته من المصفوفة. يمكنك أيضًا استخدام shift()الذي سيعطي العنصر الأول وإزالته منه y.


لا يعمل بناء الجملة لامدا عادة في IE 10 أو أقل.

أنا عادة ما تستخدم

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

يمكنك الاتصال forEach مثل هذا:

var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})

عنصر سيكون له قيمة كل فهرس من 0 إلى طول الصفيف.

انتاج:

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

كسبلايناتيون:

forEach في فئة النموذج الأولي. يمكنك أيضًا الاتصال بهذا الاسم asArray.prototype.forEach (...)؛

prototype: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

يمكنك أيضًا التبديل عبر مجموعة مثل هذه:

1    
3    
2

أعرف أن هذه رسالة قديمة ، وهناك العديد من الإجابات الرائعة بالفعل. لمزيد من الاكتمال كنت أحسب في واحدة أخرى باستخدام AngularJS . بالطبع ، هذا ينطبق فقط إذا كنت تستخدم Angular ، من الواضح ، مع ذلك ، أود أن أضعه على أية حال.

angular.forEachيأخذ وسيطتين ووسيطة ثالثة اختيارية. الوسيطة الأولى هي الكائن (صفيف) للتكرار ، والوسيطة الثانية هي وظيفة التكرار ، والوسيطة الثالثة الاختيارية هي سياق الكائن (يُشار إليها أساسًا داخل الحلقة باسم "هذا".

هناك طرق مختلفة لاستخدام حلقة forEach الزاوية. أبسط وربما الأكثر استخداما

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

طريقة أخرى مفيدة لنسخ العناصر من صفيف إلى آخر

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

على الرغم من أنك لست بحاجة إلى القيام بذلك ، يمكنك ببساطة القيام بما يلي ، وهو ما يعادل المثال السابق:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

الآن هناك إيجابيات وسلبيات استخدام هذه angular.forEachالوظيفة على عكس forحلقة النكهة المبنية بالفانيليا .

الايجابيات

  • سهولة القراءة
  • سهولة الكتابة
  • إذا كان متاحًا ، angular.forEachفستستخدم حلقة forEach ES5. الآن ، سأحصل على الكفاءة في القسم السلبيات ، لأن حلقات forEach أبطأ بكثير من الحلقات. أذكر هذا كمحترف لأنه من الجيد أن تكون متسقة وموحدة.

فكر في الحلقتين المتداخلتين التاليتين ، اللتين تقومان بالضبط بنفس الشيء. لنفترض أن لدينا صفيفين من الكائنات وكل كائن يحتوي على مجموعة من النتائج ، لكل منها خاصية قيمة هي سلسلة (أو أيا كان). ودعنا نقول أننا نحتاج إلى التكرار أكثر من كل نتيجة ، وإذا كانت متساوية ، فعليك تنفيذ بعض الإجراءات:

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

منح هذا هو مثال افتراضي بسيط جدا ، ولكني كتبت ثلاثية المضمنة لحلقات باستخدام النهج الثاني وكان من الصعب جدا قراءة ، والكتابة لهذا الأمر.

سلبيات

  • نجاعة. angular.forEach، والأصلي forEach، لهذه المسألة ، كلاهما أبطأ بكثير من forالحلقة الطبيعية .... حوالي 90 ٪ أبطأ . لذا بالنسبة لمجموعات البيانات الكبيرة ، من الأفضل الالتزام forبالحلقة المحلية .
  • لا يوجد كسر ، أو الاستمرار ، أو العودة الدعم. continueهو في الواقع مدعوم من قبل " accident " ، لتستمر في angular.forEachوضع بسيطة لك return;بيان في وظيفة مثل angular.forEach(array, function(item) { if (someConditionIsTrue) return; });الذي سيؤدي إلى استمراره خارج وظيفة ذلك التكرار. ويرجع ذلك أيضًا إلى حقيقة أن الشركة الأم forEachلا تدعم الاختراق أو تستمر أيضًا.

أنا متأكد من أن هناك العديد من الإيجابيات والسلبيات الأخرى كذلك ، ولا تتردد في إضافة أي ما تراه مناسبًا. أشعر أن ، في النهاية ، إذا كنت بحاجة إلى الكفاءة ، والتشبث فقط forحلقة المحلية لاحتياجاتك looping. ولكن ، إذا كانت مجموعات البيانات الخاصة بك أصغر حجمًا وبعض الفاعلية لا بأس من الاستسلام في مقابل قابلية القراءة والكتابة ، فبإمكانك بكل الطرق رمي angular.forEachهذا الفتى السيئ.


إذا كنت ترغب في استخدامها forEach()، سيبدو -

theArray.forEach ( element => { console.log(element); });

إذا كنت ترغب في استخدامها for()، سيبدو -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }


الحل السهل الآن هو استخدام مكتبة underscore.js . إنه يوفر العديد من الأدوات المفيدة ، مثل eachسيقوم تلقائيًا بتفويض المهمة إلى السكان الأصليين forEachإذا كانت متوفرة.

مثال CodePen عن كيفية عمله هو:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

أنظر أيضا

  • Array::forEach .
  • في for_each...in (MDN) ، يتم شرح ذلك بأنه for each (variable in object)تم إيقافه كجزء من معيار ECMA-357 ( EAX ).
  • for...of (MDN) يصف الطريقة التالية لتكرار استخدامه for (variable of object)كجزء من اقتراح Harmony (ECMAScript 6).

ربما for(i = 0; i < array.length; i++)لا يكون الحل هو الاختيار الأفضل. لماذا ا؟ إذا كان لديك هذا:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

إن أسلوب دعوة من array[0]ل array[2]. أولاً ، سيحدد هذا أولاً المتغيرات التي لا تمتلكها حتى ، وثانياً لن يكون لديك المتغيرات في الصفيف ، والثالث هذا سيجعل رمز الشفرة أكبر. انظر هنا ، هذا ما أستخدمه:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

وإذا كنت تريد أن تكون وظيفة ، فيمكنك القيام بذلك:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

إذا كنت تريد أن تنكسر ، فهناك منطق أكثر بقليل:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

مثال:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

يعود:

//Hello
//World
//!!!

طريقة jQuery باستخدام $.map:

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];

ليس هناك قدرة داخلية على كسر في forEach. لمقاطعة تنفيذ استخدام Array#someمثل أدناه:

[1,2,3].some(function(number) {
    return number === 1;
});

هذا يعمل لأنه someيرجع true بمجرد أي من الاستدعاءات ، تنفيذ في ترتيب صفيف ، إرجاع true ، short-circuiting تنفيذ الباقي. الإجابة الأصلية راجع النموذج الأولي للصفة some


هناك عدة طرق للتكرار من خلال مصفوفة في جافا سكريبت ، على النحو التالي:

ل- انها الاكثر شيوعا. كتلة كاملة من التعليمات البرمجية لحلقات

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

بينما - حلقة في حين أن الشرط من خلال. يبدو أن الحلقة الأسرع

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

القيام / أثناء - أيضًا التكرار من خلال كتلة من التعليمات البرمجية أثناء تحقق الشرط ، سيتم تشغيله مرة واحدة على الأقل

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

الحلقات الوظيفية - forEach، map، filterأيضًا reduce(يتم تكرارها من خلال الدالة ، ولكن يتم استخدامها إذا كنت بحاجة إلى إجراء شيء ما مع الصفيف ، إلخ.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

لمزيد من المعلومات والأمثلة حول البرمجة الوظيفية على المصفوفات ، انظر إلى مشاركة المدونة البرمجة الوظيفية في JavaScript: خريطة وتصفية وتقليل .


for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}






iteration