2016-09-10 3 views
1

ECMAScript仕様では、array.lengthは配列内の要素の数として定義されていません。 Javascript配列の要素数を調べるにはどうすればよいですか?

http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-array-instances-length

ある

The length property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

、JavaScriptエンジンは array.lengthは、すべての場合に正の無限大であることを引き起こす可能性があり、それが標準に準拠しているでしょう。

これを考慮すると、配列内の要素をどのように数える必要がありますか?

+0

私があなたの質問から理解しているところでは、誰かが 'array.length'プロパティを上書きすることが懸念されます。あれは正しいですか?もしそうなら、@RedMercuryが説明したような 'forEach'を使用するか、または' for''をあなたの配列にループさせて、長さを計算してください。 – shriek

+0

少なくともChromeは 'array.length'をInfinity:' Uncaught RangeError:配列の長さが無効です 'に設定することを拒否します。 – Seb

+0

これは非常に理論的な問題です。実際、array.lengthは配列の要素数と非常に強い関係があることを知っています。 –

答えて

1

これは、lengthプロパティの唯一の仕様ではありません。

抽象操作の仕様ArrayCreate(length, proto)は、lengthプロパティがlengthパラメータに初期化されていることを示しています。

Specifically, whenever an own property is added whose name is an array index, the value of the length property is changed, if necessary, to be one more than the numeric value of that array index

他の配列の操作は、これらの操作で定義されているので、lengthプロパティが正確に配列要素のインデックスを反映させる必要があります。

そしてArray Exotic Objectsの仕様は、それが更新されます方法について説明します。

1

何ですか?ちょうどarray.lengthを使用してください。配列の長さを正の無限大に設定する標準の実装が存在しないことは確かです。

array.lengthの使用を避けたい場合は、forEachを使用してください。

var arrLength = 0; 
arr.forEach(function() { 
    arrLength++ 
}) 
+0

ところで、間違っています: 'var x = [9]; x.length = 10; 'あなたの関数は1回ではなく10回繰り返します。また、' var y = [9、10、14]; y.length = 1; console.log(y); 'は' [9] 'のみを表示します。 – Seb

+0

@Sebこれは 'x'配列の両方のアカウントで実際に間違っています。上記の場合、' arrLength'が '1'になります。 'y'配列に関しては、配列の長さをより低く設定すると、その行が削除されます。実際には配列中に単一の項目があると言っているので、値 '10'と '14'を削除しています。 – vlaz

+0

私の悪い、私はそれをチェックしていない。しかし、.shift()と.pop()は異なる結果を生み出します。 – Seb

0

.lengthの変更はChromeによって禁止されています。これを実行します。

var x = []; 
 
x.length = +Infinity; // Uncaught RangeError: Invalid array length

ので、幸いにも、ここに危険性がありません。 For無限ループ。おそらくメモリの終わりのために多少早く終了​​するでしょう。

でも、これと同じようにlengthを変更することは可能です。もしそれを大きくするとどうなるでしょう?

var x = [9]; 
 
console.log(x); // [9] 
 

 
x.length = 10; 
 
console.log(x); // still [9], although length is 10 this time 
 

 
// example from Red Mercury 
 
x.forEach(function (item, index) { 
 
    console.log('Item', index, item); 
 
}); 
 
    
 
// will print: Item 0 9 
 
    
 
// But... 
 
do { 
 
    console.log(x.shift()); 
 
} while(x.length > 0); // .shift() and .pop() update .length property 
 

 
// will print 9 once, and nine times undefined 
 
// probably the same with .pop(), just in reversed order

と小さいですか?

var x = [9, 10, 14]; 
 
console.log(x); // [9, 10, 14] 
 

 
x.length = 1; 
 
console.log(x); // [9] 
 

 
// example from Red Mercury 
 
x.forEach(function (item, index) { 
 
    console.log('Item', index, item); 
 
    }); 
 
    
 
// will print: Item 0 9 
 
    
 
// But... 
 
do { 
 
    console.log(x.shift()); 
 
} while(x.length > 0); 
 

 
// will print only 9

大きな長さが.forEach()で確認することができながら、だから、小さくはできません。長さの値を変更することはお勧めしません(.forEach().shift()が「非同期化」を開始します)。しかし、あなた自身のコードでは、これはあなたに起こるべきではありません。私は言語が完全に防弾でなければならないとは考えていません。現実はブラウザでスクリプトが壊れて最終的にそれをチェックし、プログラマーをあまりにも制限する可能性があります。JavaScriptにオブジェクトのような配列だけでなく、適切な配列があれば、それは防ぐことができますが、それはそれです。

関連する問題