Frage

ich sah bei mdn Der Code, der verwendet werden sollte - wenn es keine gibt indexOf Implementierung .

Dieser Algorithmus entspricht dem in ECMA-262 angegebenen ... wie sie sagen

Und hier ist der Code:

/*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*/   }

Aber in meiner Frage geht es um Zeile Nr. 7:

Wenn ich schreibe:

[].indexOf dann - this ist das Array selbst. (Zum Teufel ist es an verbunden Array.prototype.indexOf - zuerst).

Ich meine - this wird immer einen wahren Wert sein. Also warum Gibt es diese Überprüfung?

Auch - Resharper zeigt mir dies (was vollkommen logisch ist):

enter image description here

Also - warum existiert diese Prüfung? Vermisse ich hier etwas?

War es hilfreich?

Lösung

Nicht unbedingt - es liegt daran, dass die indexOf() Native Funktion verwendet die direkte this Wert bestanden, nicht derjenige, der in ein Objekt konvertiert wurde (entspricht dem, was im strengen Modus passiert), und ein solcher Shim müsste nachdenken, um diese konform zu sein. Zum Beispiel wird dieser Code a werfen TypeError:

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

Es wird a werfen TypeError, als die this Wert wird nicht in ein Objekt umgewandelt oder in das globale Objekt geändert. In benutzerdefinierten Nicht-Strengfunktionen der Wert von this ist das globale Objekt, wenn es kein übergeordnetes Objekt gibt, aber im ES5 -strengen Modus wird es als übergeben undefined selbst. Eine andere Situation ist, wenn Sie es speziell mit beiden nennen null oder undefined:

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

In der ES5 -Spezifikation, das Dies Wert bezieht sich auf den ursprünglichen Wert als der als der bestandene Wert thisArg, ohne Änderungen. Im Nichtstreifenmodus, das Dies Wert ist in benutzerdefinierten Funktionen nicht für Code zugänglich, native Funktionen können jedoch explizit die Verwendung angeben das Dies Wert anstatt was die this Schlüsselwort bewertet zu (was als die bezeichnet wird ThisBinding in der Spezifikation). Im strengen Modus bewerten beide das gleiche.

Weil die native Version auf die nichtboxte Version der zugreifen kann this Wert im Nichtstreifenmodus (der direkt an die interne Funktion übergeben wird [[ToObject]], was a wirft a TypeError Beim Versuch zu konvertieren null oder undefined) Diese Überprüfung muss implementiert werden, um die Anforderungen der Spezifikation zu erfüllen.

Hinweis: Technisch gesehen ist das Code -Beispiel in Ihrer Frage nicht ziemlich durch die ES5 -Spezifikation als die this Wert könnte falsy sein, was ihm scheitern würde, obwohl er theoretisch vorgehen sollte (native Implementierungen von indexOf() nicht werfen, wenn false wird als die bestanden this Wert). Auch da das globale Objekt übergeben würde, wenn Der Wert war eigentlich undefiniert oder null, es würde das passieren if (!this) Test, auch wenn es nicht soll. Dies kann nicht einfach gelöst werden, indem er prüft, ob das Argument nicht das globale Objekt ist, da dies fehlschlagen würde, wenn das globale Objekt explizit verabschiedet würde (was zulässig ist).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top