質問

んjavascriptの配列として、何を感じ、矛盾もいいので説明しています。

で始ます:


var myArray = [1, 2, 3, 4, 5];
document.write("Length: " + myArray.length + "<br />");
for( var i in myArray){
   document.write( "myArray[" + i + "] = " + myArray[i] + "<br />");
}
document.write(myArray.join(", ") + "<br /><br />");
Length: 5
myArray[0] = 1
myArray[1] = 2
myArray[2] = 3
myArray[3] = 4
myArray[4] = 5
1, 2, 3, 4, 5

いていかなければなりませんこのコードが理解しているjavascriptの配列がオブジェクトでproperitiesする追加の配列は、これらのproperitiesに追加される配列のよう矛盾した。

続ける前に、どのよう注文字列値に変換できる数値です。

  • 空でない文字列->数値の文字列またはNaN

  • 空の文字列->0

でインストールし、javascriptの配列がオブジェクトの法:


myArray["someThing"] = "someThing";
myArray[""] = "Empty String";
myArray["4"] = "four";

(var i myArray){ 書きします。write("myArray["+i+"]="+myArray[i]+"<br />");} 書きします。write(myArray.join(",")+"<br /><br />");

Length: 5
myArray[0] = 1
myArray[1] = 2
myArray[2] = 3
myArray[3] = 4
myArray[4] = four
myArray[someThing] = someThing
myArray[] = Empty String
1, 2, 3, 4, four

出力は予想外でした。

に空文字列を"4"に変換され、その数値を設定する場合にmyArray["4"],このようだ。しかし、空の文字列""がなに変換され、その数値を0では空文字列となります。もの以外は空文字列"何か"がなに変換され、その数値、NaN、文字列として扱われます。いるのですか?は、決算内myArray[]内の数値は文字列。

また、されている理由は何でしょうかつ、数字、properitiesのmyArray含まれませんmyArray.長myArray.join(",")?

役に立ちましたか?

解決

JavaScriptの配列のキーは、実際には文字列です。詳細および任意のキーのマップタイプの実装では、この回答する を確認します。

<時間>

明確にし、ジェイソンは掲載内容に追加するには:JavaScriptの配列はオブジェクトです。オブジェクトは、プロパティを持っています。プロパティ名は文字列値です。したがって、配列インデックスは、同様に多くの何かが起こることができる前に、文字列に変換されます。

:プロパティ名Pは、以下の(ECMA-262、15.4)を保持していれば(つまり、特殊な配列-魔法が呼び出される)配列インデックスとして扱われます
  

のToString(ToUint32(P))Pに等しく、ToUint32(P)は2 ^ 32に等しくない - 1

の数値インデックスは列(としない他の方法で回避)に変換されることを容易に確認することができます:

var array = [];
array[1] = 'foo';
array['1'] = 'bar';
array['+1'] = 'baz';
document.writeln(array[1]); // outputs bar
<時間>

また、for..inループで配列のエントリを反復処理するためにその悪い習慣 - 誰かがいくつかのプロトタイプでめちゃめちゃ場合は、予期しない結果を得る可能性があります(そして、それは本当に速い、のいずれかではありません)。標準を使用してくださいfor(var i= 0; i < array.length; ++i)代わります。

他のヒント

これはフィロのポストするへの答えです。彼は、オブジェクトのバージョンごとに異なるプロパティ名を使用しているため、彼のベンチマークには欠陥がある:彼は同様ではなく、i x使用している必要があります。

このように、たとえば、正しく行われた場合:

var start, end, count = 1000000;

var obj = {},
    array = [];

start = new Date;
for(var i = count; i--; )
    array[i] = i;
end = new Date;
document.writeln(Number(end) - Number(start));

start = new Date;
for(var i = count; i--; )
    obj[i] = i;
end = new Date;
document.writeln(Number(end) - Number(start));

あなたは時間が非常に近くなることがわかります。 FF3.0.5では、配列バージョンは(オペラで、それは周りの他の方法です)でも一貫して遅くなります。

アレイは、JavaScriptで他のすべてのように、オブジェクトです。オブジェクトは、開発者の負担を軽減するために、のドット表記のに恵まれてきました。あなたの例を使用して

myArray["someThing"] = "someThing";

タグを書くことと同じです
myArray.someThing = "someThing";

このケースでは、オブジェクトにプロパティを追加する代わりに、アレイにそれを追加します。同じことは、空の文字列で行くあなたは、空の文字列をのドット表記を使用することはできませんが...奇妙な、ハァッ?

「4」の場合には、整数に強制することができ、したがって、アレイへのインデックスとして使用されます。

彼は、「配列インデックスが文字列に変換されている」と述べたときに

私はクリストフに反対ます。

まず、私はそれが実装に依存だと思う...私は(良い)実装がそれを行うには、いくつかのスマートな方法があり、配列アクセスを最適化すると仮定します。

実は、私は少しテストをした、そしてそれは、ほとんどのマイクロベンチマークと同様に良好であるものの、それは面白いです(つまり、超信頼性がありません。):

result = ""
var x;

var trueArray = []
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "i" + i; // To do the same operations
  trueArray[i] = 1;
}
var endTime = new Date();
result += "With array: " + (endTime - startTime) + "\n";

var sArray = []
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  sArray[x] = 1;
}
var endTime = new Date();
result += "With s array: " + (endTime - startTime) + "\n";

var objArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "i" + i;
  objArray[x] = 1;
}
var endTime = new Date();
result += "With object(i): " + (endTime - startTime) + "\n";

var sobjArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  sobjArray[x] = 1;
}
var endTime = new Date();
result += "With s object: " + (endTime - startTime) + "\n";

var iobjArray = {}
var startTime = new Date();
for (var i = 0; i < 100000; i++)
{
  x = "" + i;
  iobjArray[i] = 1;
}
var endTime = new Date();
result += "With i object: " + (endTime - startTime) + "\n";


// Then display result

IE6で、私が取得:Arrayで:オブジェクトと1453:3547
を FF 3.0で、私が取得:Arrayで:オブジェクトと83:226
を サファリ3.1で、私が取得:Arrayで:オブジェクトと140:313
を オペラ9.26で、何らかの理由で私は結果を得ることはありませんが、私はループの数の1/10に低減している場合、私が取得:Arrayで:オブジェクトと47:516
実は、私はこれを入力しながら、Operaは実行してみましょう、そして最終的に結果を得た:配列の場合:281オブジェクトの場合:166063 ...

の配列が最適化されるように!これは幸運です...
クリストフのデモンストレーションが私を感動しませんでした。私の結論は、数値として解釈できる文字列は引用符で囲まれた式と一緒に行くこれは、そのように扱われていることをより多くのだろう...

だからあなたの結果の私の解釈は、(スパース値、すなわち上の連想配列のかもしれない行動で。いくつかの孤立大きなインデックス)これらをフィードする場合、配列は、数値インデックスを持つ高速な配列のように動作しているということですが、オブジェクトとして、それはまだ性質の通常の取り扱いを持っています。しかし、これらのプロパティは、アレイ部で処理されていない、あなたが得たので、結果は(参加)。

[EDIT]私はクリストフのアイデア以下、いくつかのループを追加しました。
FF3に、私が得る:アレイと:92の配列:オブジェクト(I)93:Sオブジェクトと243:194私はオブジェクトと:125(パーフの実行の間で変化するが、概ね一致しています)。

私だ、この整数の超納得していない - >列 - >整数往復ではなく、さらにそのECMAリクエストこのシーケンス。私はそれを読み取る方法がある:プロパティが文字列であると、それはそのようなものとして扱われる、整数として解釈することができる

もちろん、知っている唯一の確実な方法は、実装を見てだろう...

私は、整数の性質または整数に変換することができるプロパティを取得無地のオブジェクトが何らかの形で最適化されて興味を持って注意してください。実装は、このケースを最適化することは興味深いと判断しておそらく、JSプログラマの多くは、配列としてプレーンなオブジェクトを使用しているため。

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