2013-04-11 15 views
12

非常にリソースが制限されている組み込みデバイス用のJavaScriptインタプリタを作成しています(http://www.espruino.com)。JavaScriptを正しく実装したと思うたびに間違っていると思います。JavaScript []は本当にどのように機能しますか?

私の質問は約[]です。 JavaScriptの最も基本的な部分を正しく実装するにはどうすればよいでしょうか?

私はJavaScriptの仕様を見てきましたが、正しいビットを見つけられなかったかもしれませんが、役に立つ答えが見つかりません。

私はこれまで、整数と文字列の2つの「マップ」が効果的に存在すると想定していました。そして配列の長さは最高の整数に1を加えた値でした。

var a = []; 
a[5] = 42; 
a["5"]; // 42 
a.length; // 6 

も:しかし、これはクロムのjsconsoleによると、間違っているようだ

var a = []; 
a["5"] = 42; 
a[5]; // 42 
a.length; // 6 

そう...素晴らしい - すべてが文字列に変換され、整数を表し、最高値文字列れます長さを取得するために(プラス1)使用されていますか?違う。

var a = []; 
a["05"] = 42; 
a.length; // 0 

"05"は、8進数でも有効な整数です。それでなぜそれが長さに影響しないのですか?

文字列を整数に変換してから、文字列に変換して一致するかどうかを確認する必要がありますか?

配列やオブジェクトに項目を格納して取得するために使用される正確なアルゴリズムについてのリファレンスはありますか?それは非常にシンプルでなければならないようですが、実際にはそうではないように見えます!

+6

[標準](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4)は、「*プロパティ名 'P'(' String'の形で) ToString(ToUint32(P))が 'P'で、' ToUint32(P) 'が' 2 ** 32-1'。* "と等しくない場合にのみ、配列インデックスです。 – DCoder

+6

あなたがインタプリタを書いているなら、仮定は使用すべきではありません。あなたは仕様を読んでいるはずです。 –

+0

V8など、既存の強力で標準に準拠したJS実装を使用してみませんか?私がhttp://www.espruino.com/Performanceで読んだことは恐ろしいものでした: -/ – Bergi

答えて

4

は、前記他の人が注目された:

「(文字列値の形で)プロパティ名Pは、配列インデックスである場合に限りのToString(ToUint32(P)) ToUint32(P)が2^32-1に等しくない場合に発生します。

console.log("5" === String("5" >>> 0)); 
// true, "5" is equal to "5", so it's an index 

console.log("05" === String("05" >>> 0)); 
// false, "05" is not equal to "5", so it's not an index 

注:Zero-fill right shiftは数をシフト、ToUint32の代替を持っているJSで最短の方法ですあなたのシナリオで"5"は、配列のインデックスと考えると"05"ではないされている理由を説明しています

ゼロによって。

+0

ありがとう - これは配列の長さの問題についても説明しています。仕様へのリンクをありがとうDCoder –

3

配列は単なるオブジェクトです。つまり、配列の要素と見なされない追加のプロパティを持つことができます。

角括弧の引数が整数の場合は、それを使用して配列への代入を実行します。それ以外の場合は、文字列として扱い、配列オブジェクトのプロパティとして格納します。

編集delnanさんのコメントとDCoderさんのコメントに基づいて、これは(単にプロパティ対)の配列のための適切な指標である場合にはJavaScriptを決定する方法である: http://www.ecma-international.org/ecma-262/5.1/#sec-15.4

+0

最後の部分は、あなたが*正確に*「整数」とは何かを定義しない限り、特に有用ではありません。たとえば、 "05"は整数で、なぜ(not)ですか? – delnan

4

MDN

を参照してください。 JavaScript配列インデックスも引用することは可能です(例: 年[2]ではなく[年] [2])。ただし、これは必須ではありません。とにかく、暗黙的なtoString変換を通じて、 年[2]の2はJavaScript エンジンによって文字列に強制的に変換されます。

console.log(years["2"] != years["02"]); 

だからa["5"]とあなたがいる間、アレイにアクセスしている:それは「2」と「02」 上の2つの異なるスロットを参照することになり年オブジェクトおよび次の例では、真のログに記録することを この理由のためでありますa["05"]は、配列オブジェクトにプロパティを設定します。

1

アレイもオブジェクトです。あなたは同じことをやっているこの

a["05"] = 5; 

を行うことにより

:プロパティは、ドットの後に指定されているように、

a.05 = 5; 

しかし、上記の構文エラーになりますことができません数字で始まります。

あなたがもしそうなら、この:

a = []; 
a["05"] = 5; 

それでも空の配列が、05という名前aの性質を持っている価値5を持っています。

数(したがって満たされない要件"05"の場合)ToString(ToUint32(x))xに等しい場合にのみxis an array index。スペックとして

関連する問題