この記事は、JavaScript ユニバーサル ループ トラバーサル メソッド forEach で言及されている疑似配列に関する最後の質問に答えます。
擬似配列とは何ですか?
Array.prototype.slice を通じて実際の配列に変換できる長さ属性を持つオブジェクト。
このようなオブジェクトは数多くありますが、より特別なものは引数オブジェクトであり、getElementsByTagName、document.childNodes などの呼び出しです。それらはすべて、疑似配列である NodeList オブジェクトを返します。
Array.prototype.slice.call(fakeArray) を通じて、擬似配列を実際の Array オブジェクトに変換できます。
例を見てみましょう:
var fakeArray01 = { 0:'a',1:'b',length:2};//これは標準の疑似配列オブジェクトです
var arr01 = Array.prototype.slice.call(fakeArray01); >alert( arr01[0]);//a
var arr02 = [].slice.call(fakeArray01);
alert(arr02[0]);//a
slice OK 配列の断片を取得するために使用され、新しい配列を返し、元の配列は変更されません。
この例では、fakeArray が Array オブジェクトに正常に変換されていることがわかります。おそらく皆さんは Array.prototype.slice.call の記述方法に慣れていないでしょう。実際、[].slice.call を使用しても同じ効果を実現できます。では、なぜプロトタイプを使用して実装する必要があるのでしょうか。プログラムがより効率的に実行され、コードもより美しくなります。
擬似配列の実装
擬似配列の実装を詳しく見てみましょう。
いくつかの特殊な使用例を見てみましょう:
var fakeArray01 = {a:'a',b:'b',length:2};//長さの添字に対応する値がありません
var arr01 = Array.prototype.slice.call (fakeArray01);
alert(arr01[0]);//未定義
var fakeArray02 = {0:'a',1:'b',length:'num'};//長さは数値
var arr02 = Array.prototype.slice.call(fakeArray02);
alert(arr02[1]);//未定義
同様にfakeArray01とfakeArray02は実数に変換されます
V8 エンジン
array.js
のソースコードを見ると、内部実装を簡素化できます function slide(start, end) {
var len = ToUint32(this.length ), result = [];
for(var i = start; i result.push(this[i] );
}
return result;
}
スライスはこれが配列型である必要はなく、長さ属性を持つ必要があるだけであることがわかります。また、length 属性は数値型である必要はありません。数値に変換できない場合、ToUnit32(this.length) は 0 を返します。
上記の結論に基づいて、fakeArray01 は次のように変換されると結論付けることができます。長さ 2 の配列、その値はすべて未定義に初期化され、fakeArray02 は長さ 0 の配列に変換されます。添え字 1 を持つ要素への自然なアクセスは未定義を返します
IE の問題
標準ブラウザ スライス実装ではすでにすべての問題を説明できますが、IE NodeList の処理中に問題が発生しました。 IEではNodeListを実配列に変換できずエラーが発生します。これはなぜでしょうか?厳密にはIE内でArrayoidという抽象クラスが定義されており、ArrayもArgumentsもこれを継承しているのでsliceが使えます。ただし、DOM オブジェクトは COM 経由で JScript に接続されており、スライスの検出は失敗します。
Jquery と擬似配列
Jquery は内部で擬似配列を広範囲に使用します。 Jquery オブジェクト全体が擬似配列に基づいて構築されていると言えるので、Jquery の実際のアプリケーションをいくつか見てみましょう:
;
fakeArray