例 1:
var obj={0: 'a' ,1:'b'}
alert(obj.length); //未定義
var arr=['a','b']
alert(arr.length); 2
上記の例から、配列のようなオブジェクトの長さ属性は、格納されるデータの量に直接リンクされていません。インデックス属性 (0, 1) と長さ属性の両方が存在します。オブジェクトの通常の属性と同様に、それらの間には関係はありません。js エンジンは、格納されたデータの量に基づいて配列のようなオブジェクトの長さを自動的に計算しません。
しかし、配列のようなオブジェクトの長さは、格納されるデータの量と本当に何の関係もないのでしょうか?例 2 は、これが当てはまらないことを示しています。
例 2:
関数 myarr(){}
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc' ]);
alert( m.length);//IE8 以下: 未定義 その他のブラウザ: 3
alert(m[2]);// IE8 以下: 未定義 その他のブラウザ: 'xiaoc'
From 例 2 でわかるように、IE8 より前のバージョンを除き、配列メソッドを強制的に使用して配列状のオブジェクトに要素を追加すると、オブジェクトの長さ属性も計算されます。 IE8 より前のバージョンでは、配列のようなオブジェクトに要素を追加するための配列メソッドの使用の強制はサポートされていないようです。
例 3:
この例では、例 2 の myarr コンストラクターに初期化操作を追加し、配列のようなオブジェクトが初期化されるときに要素を追加します。
function myarr(){this[0]='cc';}
var m =new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//ie8 より下: 未定義その他: 3
alert(m[2]);//ie8 以下: 未定義 その他: xiaoc
ie8 以下のブラウザは引き続き配列メソッドの強制使用をサポートしません。次の例で議論します。他のブラウザの場合、長さ属性の出力は 3 で、インデックス 2 の要素は 'xiaoc' ですが、明らかに、JS エンジンは配列のようなオブジェクトにもともと存在していたインデックス 0 の要素 'cc' を完全に無視します。次の例を見てみましょう。この例では、例 3 に基づいて長さ属性に追加の初期化を追加します。
function myarr(){this[0]='cc'; this.length=1;}//長さの初期化をもう 1 つ追加します
var m=new myarr () ;
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//出力 4
alert( m[ 2]);//Output 'lai'
今度は、すべてのブラウザ (ie6 7 を含む) が正しく 4 を出力し、インデックス 2 の要素が ' として正しく出力されました。 lai ' を見ると、IE 6 と 7 で length 属性の初期化が追加された後、配列メソッドが正常に使用できるようになっていることがわかります。
次に、長さ属性を不正な型に初期化してみます。
例 4:
function myarr(){this[0]='cc'; this.length="bo";}//length は数値に変換できない不正な型に設定されています
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length); /output 3
alert(m[2]);// 出力 'xiaoc'
function myarr(){this[0]='cc'; this.length="1";}//length が不正な型に設定されています。数値に変換できます
Array .prototype.push.apply(m,['cson','lai','xiaoc']);//出力 4
alert(m[2]);/ /output 'lai'
上記のすべての例から、配列メソッドを使用する場合 (ここではプッシュを例として取り上げます)、プロセスはおおよそ次のようになることが推測できます:
IE6 7:
次のことがわかります。 IE6 7はサポートされていないわけではありません。要素を追加するには配列メソッドを使用する必要がありますが、最初にlength属性が存在するかどうかを判断し、存在しない場合は何もせずに戻ります。長さ属性が不正な値の場合は、数値型への変換を試みます。変換が失敗すると、長さは 0 に設定されます。これにより、例 2 と 3 の未定義の出力と、例 4 の正しい出力が解析されます。
その他のブラウザ:
他のブラウザは、長さ属性に基づいて異なる操作を実行します。長さ属性が存在しない場合は、長さを 0 に設定します。長さ属性が不正な値の場合は、変換を試みます。変換が失敗した場合は、 length も 0 に設定されます。
長さ属性は配列メソッドにおいて非常に決定的な役割を果たすため、JS エンジンは長さ属性に不正な値を書き込むことを禁止しています:
var arr=['1','2','3'];
arr.length= 'unknown';/ /無効な配列の長さを報告するエラー
上記の例から、次の結論を導き出すことができます。配列のようなオブジェクトを使用する場合、さまざまな不正な長さによって引き起こされる奇妙な問題を回避するためです。計算では、配列のようなオブジェクトを初期化するときに長さ属性の値を初期化する必要があります。初期化中に要素が追加されたが、長さ属性の値が設定されていない場合、配列メソッドを使用する場合、IE6 7 はすべての操作を無視します。他のブラウザは初期化中に要素の追加を無視します。
さらに、長さ属性によって引き起こされる別の問題:
例 5 を参照してください:
function myarr(){}
myarr.prototype=new Array();
var m=new myarr(); Push( 'cson','lai','xiaoc');
alert(m.length);//IE6 7: 0 その他: 3
alert(m[2]);//すべてのブラウザ: ' xiaoc'
配列のプロトタイプ継承を使用する場合、IE 6 および 7 では長さは常に 0 になります。要素の数に関係なく、他のブラウザーは正常に動作します。
強制的にlength属性を設定してもIE6では死活は0 7:
function myarr(){}
myarr.prototype=new Array();
var m=new myarr(); 10;
alert(m.length );//IE6 7:0 その他: 10
したがって、次のように結論付けることができます: オブジェクト プロトタイプが IE6 7 で配列を継承すると、length 属性は次のようになります。常に 0 であるため、配列のようなオブジェクトが array メソッドを使用する必要がある場合は、配列を継承せずに Array.prototype.xxx.apply(obj,[]) メソッドを使用し、忘れずに正しく初期化する必要があります。長さ属性の値。