Question

J'ai vu à MDN le code qui doit être utilisé - s'il n'y a pas indexOf la mise en oeuvre .

Cet algorithme correspond à celui spécifié dans ECMA-262 ... comme ils disent

Et voici le 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*/   }

Mais ma question concerne la ligne n ° 7:

Si j'écris:

[].indexOf alors - this est le tableau lui-même. (Diable, il est attaché à Array.prototype.indexOf - en premier lieu).

Je veux dire - this sera toujours la valeur de la vraie. alors Pourquoi Ce chèque existe-t-il?

Aussi - Resharper me montre cela (qui est parfaitement logique):

enter image description here

Alors - pourquoi ce chèque existe-t-il? Est-ce que j'ai râté quelque chose ?

Était-ce utile?

La solution

Pas nécessairement - c'est parce que le indexOf() La fonction native utilise le direct this La valeur passée, pas celle convertie en un objet (équivalent à ce qui se passe en mode strict), et une telle cale devrait vérifier que cela soit conforme. Par exemple, ce code lancera un TypeError:

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

Il lancera un TypeError, comme le this La valeur n'est pas convertie en un objet ou modifiée à l'objet global. Dans les fonctions non strictes définies par l'utilisateur, la valeur de this est l'objet global s'il n'y a pas d'objet parent, mais en mode strict es5, il est passé comme undefined lui-même. Une autre situation est lorsque vous l'appelez spécifiquement avec l'un ou l'autre null ou undefined:

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

Dans la spécification ES5, la cette évaluer se réfère à la valeur d'origine adoptée comme le thisArg, sans aucun changement. En mode non stricte, la cette évaluer n'est pas accessible au code dans des fonctions définies par l'utilisateur, mais les fonctions natives sont capables de spécifier explicitement l'utilisation de la cette évaluer Au lieu de ce que le this Le mot-clé évalue (qui est appelé ThisBinding dans la spécification). En mode strict, ils évaluent tous les deux la même chose.

Parce que la version native peut accéder à la version non à boîte this Valeur en mode non stricte (qui est directement transmis à la fonction interne [[ToObject]], qui jette un TypeError en essayant de convertir null ou undefined), ce chèque doit être mis en œuvre pour satisfaire les exigences de la spécification.

Remarque: Techniquement, l'échantillon de code dans votre question n'est pas assez par la spécification ES5, comme le this la valeur pourrait être fausse, ce qui l'échouerait même si elle devrait se dérouler en théorie (implémentations natives de indexOf() Ne jetez pas si false est passé comme le this évaluer). De plus, puisque l'objet global serait passé si la valeur de cette valeur était en fait indéfini ou nul, il passerait le if (!this) tester, même quand ce n'est pas censé le faire. Cela ne peut pas être résolu simplement en vérifiant que l'argument n'est pas l'objet global, car cela échouerait si l'objet global était explicitement passé (ce qui est autorisé).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top