كيفية استبعاد الأساليب المضافة إلى Array من المعالجة في حلقة "for..in"؟(جافا سكريبت)

StackOverflow https://stackoverflow.com/questions/1809505

  •  05-07-2019
  •  | 
  •  

سؤال

لقد أضفت بعض المساعدين المفيدين إلى Array (مثل toSource() للأوبرا).و الأن for..in إرجاع الوظائف ذات الخصائص العادية.

أنا استخدم for..in الآن، لأن الكود أسهل في القراءة معه.وهي وظيفة أصلية لـ js، لذا يجب أن تكون أسرع.

لكن إضافة عمليات التحقق من النوع في الحلقة يجعل من السهل استخدام الطريقة الكلاسيكية for(;;).

هل هناك أي طرق لتجنب for..in تعداد الوظائف؟

العمل عبر المتصفحات ليس ضروريًا جدًا (يجب أن يعمل في Opera)، لكن السرعة مهمة.

شكرًا لك.


يحرر:
هل هناك أي القدرة على تجنب for..in تعداد الوظائف أو الخصائص المخصصة من أي كائن؟

هل كانت مفيدة؟

المحلول

يجب أبداً استخدم حلقات for..in للتكرار على عناصر المصفوفة.for..in مُصمم للتكرار ملكيات, ، ويجب استخدامه لذلك فقط، للسبب الذي وصفته للتو.تقوم العديد من المكتبات بتعديل النماذج الأولية للمصفوفة والتاريخ وما إلى ذلك، لذا لا يجب الاعتماد على for..في تكرار عناصر المصفوفة فقط.استخدم الطريقة for(;;) فهي مضمونة للقيام بما تريد.وهي ليست أسرع من حلقة for..in، لأنها أصلية في جافا سكريبت أيضًا.

لمزيد من المعلومات، اقرأ عنها في prototype.js مكتبة.

نصائح أخرى

نعم، ولكنه JavaScript 1.7+ - فقط.يتمتع Opera فقط بدعم محدود لـ JavaScript 1.7، والذي يتضمن دعمًا أساسيًا للغاية لمهمة التدمير، لذلك لن يعمل هذا في Opera ولكنه سيعمل في Firefox.

يسمح هذا التنفيذ بالاستخدام الآمن for [each](item in array):

Array.prototype.__iterator__ = function (flag) {
    var len = this.length, i = 0;

    for (; i < len; i++) {
        yield flag ? i : this[i];
    }
};

كما ذكر آخرون، يجب ألا تستخدم for..in للتكرار على المصفوفات.إنه أبطأ من استخدام for(;;).

يجب عليك أيضًا تخزين طول المصفوفة مؤقتًا إذا كنت مهتمًا بالأداء، مثل:

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

استخدم فقط for..in للتكرار على خصائص الكائنات.لاستبعاد الخصائص الموروثة، استخدم الأسلوب hasOwnProperty() :

for (var prop in object)
{
  // Don't include properties inherited from the prototype chain
  if (object.hasOwnProperty(prop))
  {
    ...
  }
}

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

Object.defineProperty( Array.prototype, "myNewMethod", {
   value: function(){},
   writable: true,
   enumerable: false, /* this controls for..in visibility */
   configurable: true
});

ما تصفه هو بالضبط سبب استخدامك

for (var i=0; i<arr.length; i++) { ... }

بدلاً من:

for (var item in arr) { ... }

لأنهم مختلفون.

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

يحرر:تم تصحيح نوع الاستخدام الخاطئ بفضل تعليق @Bergi

نقطة جيدة حول الأداء عند التكرار على صفائف متفرقة (جدًا) - أقترح أن استخدام isNaN(parseInt()) في الحلقة يتيح لك العثور على عناصر المصفوفة فقط:

for( var propertyName in myArray){
    if( !isNaN(parseInt(propertyName)) ){ /* probably array element */ }
}

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top