質問

私が見た 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 渡された値は、オブジェクトに変換されたものではなく(厳密なモードで起こることに相当)、そのようなシムは、これが準拠するためにチェックする必要があります。たとえば、このコードはaをスローします TypeError:

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

それはaを投げます TypeError, 、として this 値はオブジェクトに変換されたり、グローバルオブジェクトに変更されたりしません。ユーザー定義された非ストライク機能では、の値 this 親オブジェクトがない場合はグローバルオブジェクトですが、ES5の厳密なモードでは、 undefined 自体。別の状況は、どちらかと特に呼び出すときです null また undefined:

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

ES5仕様では、 これ 価値 として渡された元の値を指します thisArg, 、変更なし。非ストライクモードでは、 これ 価値 ユーザー定義の関数ではコードにアクセスできませんが、ネイティブ機能はの使用を明示的に指定できます これ 価値 何の代わりに this キーワードは( ThisBinding 仕様内)。厳密なモードでは、彼らは両方とも同じことを評価します。

ネイティブバージョンがボックス化されていないバージョンにアクセスできるため this 非ストリクトモードで値(これは内部関数に直接渡されます [[ToObject]], 、それはaを投げます TypeError 変換しようとすると null また undefined)、このチェックは、仕様の要件を満たすために実装する必要があります。

注:技術的には、質問のコードサンプルはそうではありません とても ES5仕様によって、 this 価値はfalsyである可能性があり、理論で進行する必要がある場合でも失敗するでしょう(のネイティブの実装 indexOf() もしは投げないでください false として渡されます this 価値)。同様に、グローバルオブジェクトは渡されるので この値 実際には未定義またはヌルでした、それは if (!this) テストは、それが想定されていない場合でも。これは、引数がグローバルオブジェクトではないことを確認するだけで解決することはできません。これは、グローバルオブジェクトが明示的に渡された場合(許可されている)場合に失敗するためです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top