オブジェクトキーとして数値型を使用する方法はありますか?


97

オブジェクトのキー名として数値型を使用すると、常に文字列に変換されるようです。とにかく実際に数値として保存する方法はありますか?通常の型キャストは機能していないようです。

例:

var userId = 1;
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);

Dir出力:

{
    '1': 'a value'
}

私が欲しいのはこれです:

{
    1: 'a value'
}

助言?


回答:


109

いいえ、できません。 キーは常に文字列に変換されます。プロパティアクセサーのドキュメントを見る

プロパティ名は文字列でなければなりません。つまり、文字列以外のオブジェクトはオブジェクトのキーとして使用できません。数値を含むすべての非文字列オブジェクトは、toStringメソッドを介して文字列に型キャストされます。

> var foo = {}
undefined

> foo[23213] = 'swag'
'swag'

> foo
{ '23213': 'swag' }

> typeof(Object.keys(foo)[0])
'string'

1
それはかなり主観的です。ウィリアムが指摘したように、整数キーの代わりに配列を使用できます。ほとんどのJSエンジンは、バックグラウンドでスパース配列を使用できます。
Matthew Flaschen

7
配列であっても、すべてのプロパティ名は文字列に変換されます。
Tim Down

2
@ Roamer-1888:そうではありません。唯一の違いは、配列に数値プロパティを割り当てると、配列のlengthプロパティに影響することです。
Tim Down 14

2
@TimDown、そして私が言っているのはあなたが間違っているということです。「配列に数値プロパティを設定すると、長さプロパティに影響する可能性があります」という記述は正しくありません。JavaScriptの配列プロパティは、配列要素から完全に独立しています。人々を混乱させるのは、たとえば「1」が整数の文字列表現であり、それが完全な言語学的ナンセンスであるという理由だけで、連想構文がプロパティを設定しているようmyArray["1"] = foo見えることですが、それはJavascriptです。
Roamer-1888 14年

4
@ Roamer-1888:「Javascript配列プロパティは配列要素から完全に独立しています」は正しくないステートメントです。プロパティを設定しているように見えるmyArray["1"] = fooだけでなく、実際にはプロパティの定義のあらゆる意味で(キー「1」を使用して)プロパティを設定しています。たとえば、利回り。意味的には、このプロパティは数値キーがあるため「要素」と見なすこともできますが、配列の「要素」と配列のプロパティを区別するものはありません。仕様を読んでください。それでも同意しない場合は、出典を引用してください。myArray.hasOwnProperty("1")true
ハンス

23

オブジェクトではありませんが、このアプリケーションにはMapが非常に役立つことがわかりました。ここで、数値ベースのキーベースのイベントに使用しました。

onKeydown(e) {
  const { toggleSidebar, next, previous } = this.props;

  const keyMapping = new Map([
    [ 83, toggleSidebar ],  // user presses the s button
    [ 37, next          ],  // user presses the right arrow
    [ 39, previous      ]   // user presses the left arrow
  ]);

  if (keyMapping.has(e.which)) {
    e.preventDefault();
    keyMapping.get(e.which)();
  }
}

1
エレガントなLudumdareエントリの101 !+1
カイザー

11

ECMA-262-5の仕様によると思われます。

プロパティ識別子タイプは、プロパティ名をプロパティ記述子に関連付けるために使用されます。プロパティ識別子タイプの値は、形式(名前、記述子)のペアです。名前は文字列で、記述子はプロパティ記述子の値です。

ただし、ECMA-262-3には明確な仕様がありません。とにかく、文字列以外をプロパティ名として使用しようとはしません。


2

このようなものが必要ですか?

var userId = 1;var myObject ={};
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);

コンソール:オブジェクト

1:「値」


0

上記のものを番号としてアクセスするために使用したい場合は、次のことを実行できると思います。同じようにして作業しました。

var myObj = {"0":"a","1":"b","CNT":2};
$.each(myObj,function(key,value){
     if(isNaN(parseInt(key))){
          return true; //continue;
     }
     //Code to perform operation
}

これは、キーが数字で始まっていない場合にのみ機能します。それ以外の場合は、数字に変換されます。次の例を参照してください。

parseInt("45kjghk") === 45

ここではjQueryを使用しました


更新しました:

var myObj = {"0":"a","1":"b","CNT":2};
$.each(myObj,function(key,value){
     if(isNaN(parseInt(key)) || (key.length !== parseInt(key).toString().length) ){
          return true; //continue;
     }
     //Code to perform operation
}

それは上記の問題を克服するかもしれません。可能な場合は、より良い提案をしてください。ある場合は、この回答に問題があります。


-3

JavaScriptでは、数値文字列と数値は交換可能であるため、

myObject[1] == myObject['1']

数値をオブジェクトのキーにしたい場合は、配列(つまり、new Array()またはで作成[])が必要な場合があります。


2
回答ありがとうございますが、これは完全に正確ではありません。数値はtypeofから 'number'としてのみ返され、文字列ではその逆になります。
スポット

@william '数値文字列と数値は交換可能です'は正しくありません。数字は数字であり、文字列は文字列です。Object.prototype.toString.call(someObject)問題は、数値をキーとして使用できないことを参照してください。
mikemaccana 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.