سؤال

لقد رأيت في MDN الرمز الذي يجب استخدامه - إذا لم يكن هناك indexOf تطبيق .

تتطابق هذه الخوارزمية مع تلك المحددة في ECMA-262 ... كما يقولون

وهنا الكود:

/*1*/   if (!Array.prototype.indexOf) {
/*2*/     Array.prototype.indexOf = function (searchElement , fromIndex) {
/*3*/       var i,
/*4*/           pivot = (fromIndex) ? fromIndex : 0,
/*5*/           length;
/*6*/   
/*7*/       if (!this) {
/*8*/         throw new TypeError();
/*9*/       }
/*10*/   
/*11*/       length = this.length;
/*12*/   
/*13*/       if (length === 0 || pivot >= length) {
/*14*/         return -1;
/*15*/       }
/*16*/   
/*17*/       if (pivot < 0) {
/*18*/         pivot = length - Math.abs(pivot);
/*19*/       }
/*20*/   
/*21*/       for (i = pivot; i < length; i++) {
/*22*/         if (this[i] === searchElement) {
/*23*/           return i;
/*24*/         }
/*25*/       }
/*26*/       return -1;
/*27*/     };
/*28*/   }

لكن سؤالي حول السطر رقم 7:

إذا كتبت:

[].indexOf ومن بعد - this هو الصفيف نفسه. (هيك ، وهو مرتبط بـ Array.prototype.indexOf - في المقام الأول).

أعني - this ستكون دائما قيمة الحقيقة. لذا لماذا هل هذا الشيك موجود؟

أيضًا - يظهر لي Resharper هذا (وهو منطقي تمامًا):

enter image description here

إذن - لماذا يوجد هذا الشيك؟ نسيت شيئا ما هنا ؟

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

المحلول

ليس بالضرورة - لأن indexOf() تستخدم الوظيفة الأصلية المباشرة this تم تمرير القيمة ، وليس تلك التي تم تحويلها إلى كائن (أي ما يعادل ما يحدث في الوضع الصارم) ، وسيحتاج هذا اللمعان إلى التحقق من أن يكون ذلك متوافقًا. على سبيل المثال ، سوف يرمي هذا الرمز TypeError:

var a = Array.prototype.indexOf;
a();

سوف يرمي أ TypeError, ، كما this لا يتم تحويل القيمة إلى كائن أو تغييره إلى الكائن العالمي. في الوظائف غير المعرفة من قبل المستخدم ، قيمة this هل الكائن العالمي إذا لم يكن هناك كائن أولي undefined بحد ذاتها. موقف آخر هو عندما تسميه على وجه التحديد مع أي منهما null أو undefined:

"use strict";
Array.prototype.indexOf.call(null); // TypeError, what else can we do?

في مواصفات ES5 ، ال هذه القيمة يشير إلى القيمة الأصلية التي تم تمريرها كـ thisArg, ، دون أي تغييرات. في الوضع غير الشريط ، ال هذه القيمة لا يمكن الوصول إليها من الكود في الوظائف المعرفة من قبل المستخدم ، ولكن الوظائف الأصلية قادرة على تحديد استخدام بشكل صريح ال هذه القيمة بدلا من ما this يتم تقييم الكلمة الرئيسية (التي يشار إليها باسم ThisBinding في المواصفات). في الوضع الصارم ، كلاهما يقيمون نفس الشيء.

لأن الإصدار الأصلي قادر على الوصول إلى الإصدار غير المغطى من this القيمة في الوضع غير الشريط (الذي يتم تمريره مباشرة إلى الوظيفة الداخلية [[ToObject]], ، الذي يرمي أ TypeError عند محاولة التحويل null أو undefined) ، يحتاج هذا الشيك إلى تنفيذها لتلبية متطلبات المواصفات.

ملاحظة: من الناحية الفنية ، فإن عينة الكود في سؤالك ليست الى حد كبير بواسطة مواصفات ES5 ، مثل this قد تكون القيمة فاسدة ، والتي ستفشل على الرغم من أنها يجب أن تستمر من الناحية النظرية (التطبيقات الأصلية indexOf() لا ترمي إذا false تم تمريره كما this القيمة). كذلك ، نظرًا لأنه سيتم تمرير الكائن العالمي إذا هذه القيمة كان في الواقع غير محدد أو فارغ ، فسيتمرير if (!this) اختبار ، حتى عندما لا يكون من المفترض. لا يمكن حل هذا ببساطة عن طريق التحقق من أن الوسيطة ليست هي الكائن العالمي ، لأن هذا سيفشل إذا تم تمرير الكائن العالمي بشكل صريح (المسموح به).

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