- ベストアンサー
連想配列とオブジェクトの違いと挙動についての質問
- 連想配列とオブジェクトの違いと挙動について質問です。
- 質問者はデータ操作中によく分からないデータになったので、連想配列とオブジェクトのどちらであるか知りたいと述べています。
- 具体的なコード例を示しながらの質問であり、質問者は配列の中にオブジェクトを格納することについても疑問を持っています。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
#1 です。 連想配列ではありませんが、ES6 規定の Map が re97 さんの求めるものに近いかもしれません。 Object と違い、「定義順で反復処理」できますし、「key を追加すれば length に反映」されます。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map --- うすうすお気づきだと思いますが、ECMAScript の new Array は数値添字配列(かつオブジェクト型ですし、new Object は key と value を定義できるだけで「配列」としての機能はありません。 あくまで「連想配列」を求めるのなら var a = [{key1: '佐藤'}, {key2: '鈴木'}]; のように定義して for, forEach で走査するのが現実解だと思います。 ES6 が普及したら Map に移行すればいいでしょう。 # Re: re97 さん
その他の回答 (6)
- Gotthold
- ベストアンサー率47% (396/832)
「連想配列」という言葉ですが、 私は「文字列をキーにして値を取得できるデータタイプ」の意味で使っているので 私の回答についてはそのように解釈してください。 (なので、Objectを「文字列をキーにして値を取得できるデータタイプ」として使える、のように言い換えても良いです。) また、私の回答の中では、「連想配列」の要件に lengthプロパティや配列のメソッド、順序保持は含めていないです。 「配列」も非負整数をキーにして値を取得できればよくて lengthとか各種メソッドが配列の本質的な要件とは考えてなかったですね。 (もちろんあったら便利だけど。) 実際C言語だと、配列にlengthやメソッドに相当するものは無かったし。
お礼
補足ありがとうございました。 >「連想配列」という言葉ですが、 >私は「文字列をキーにして値を取得できるデータタイプ」の意味で使っている ・どこまでの機能を指して「連想配列」と看做すか、の違いだと解釈しました ・参考になりましたー
- think49
- ベストアンサー率59% (285/482)
#1,4 です。 意見の相違が見られるようなので、私が「new Object が連想配列ではない」と思う根拠を示しておきます。 1. ECMAScript で連想配列が定義されていない 言葉通りです。 少なくとも、ECMAScript 5 までに連想配列の文字は出てきません。 2. lengthプロパティがない 「配列」というからには配列の長さを確認できなければなりません。 3. 配列のメソッドを使えない 連想「配列」なのですから forEach のような配列用メソッドがあってしかるべきです。 4. 定義順で列挙できない for-in は ES5 規定では列挙順がランダムです。 --- var obj = {key2: 'hoge', key1: 'foo'}; for (key in obj) { if (obj.hasOwnProperty(key)) { console.log(key + ': ' + obj[key]); } } --- Google Chrome 38 では定義順(key2 -> key1)で列挙してくれましたが、全ての実装で同じ順序で列挙される保証はありません。
お礼
回答&詳細な説明、ありがとうございました。 ・「キーと値のペア」という点だけみれば連想配列と同じだが、実際にはこれだけ相違点がある、ということでしょうか? ・大変参考になりましたー >Google Chrome 38 では定義順(key2 -> key1)で列挙してくれましたが、全ての実装で同じ順序で列挙される保証はありません ・情報ありがとうございました ・ブラウザの挙動から勝手に仕様を推測する、のは止めた方がよいことが分かりました ・参考になりましたー
- b0a0a
- ベストアンサー率49% (156/313)
JavaScriptのオブジェクトは連想配列です。 ただしkeyにはStringかSymbolしか使えません。 もしそれ以外の型を使うと文字列化されて利用されます。 keyにオブジェクト等を使いたいのであればMapを使ってください。 また、将来的にはオブジェクト同士の関係を作れるようにもなります。 https://github.com/zenparsing/es-abstract-refs
お礼
回答ありがとうございました。 >keyにはStringかSymbolしか使えません ・Symbolって何だろうと思い調べたら、ES6から導入される新しい型なんですね ・型が増えるとか想像もしてなかったのでびっくりしましたー
- Gotthold
- ベストアンサー率47% (396/832)
> ・それとも、console.logが単にそうなっているから? console.logがそうなっているだけの話で、正直どうでも良いと思う。 standardがあるわけでもないし、console.log作った人がこんな風に表示したら分かりやすいと考えただけじゃないの? var t = []; t[0] = "A"; t[1] = "B"; t[2] = "C"; t[3] = "D"; t[6] = "E"; t[9] = "F"; console.log(t); //Firefox => Array [ "A", "B", "C", "D", , , "E", , , "F" ] //Google Chrome => ["A", "B", "C", "D", 6: "E", 9: "F"]
お礼
回答ありがとうございました。 >standardがあるわけでもないし、console.log作った人がこんな風に表示したら分かりやすいと考えただけ ・console.log結果って、ブラウザ間によってこんなにも違うんですね ・かなりびっくりしましたー
- think49
- ベストアンサー率59% (285/482)
ECMAScript に「連想配列」は存在しません。 t2 は配列初期化子で初期化しているので配列であり、オブジェクトです。 # Re: re97さん
お礼
回答ありがとうございましたー
- Gotthold
- ベストアンサー率47% (396/832)
JavaScriptでオブジェクトと連想配列は同じものですよ。 連想配列によってオブジェクトを実現していると言ったら分かりますか? > var t1 = { key1: '佐藤' , key2: '鈴木' }; このt1だってt1['key1']のように文字列をキーにして要素にアクセスできるので 連想配列そのものです。 (そもそもの話として、連想配列が文字列をキーにして要素にアクセスできる配列のことであるというのは分かってますよね?) > console.log("t2['佐藤']"); //鈴木 ケアレスミスでしょうけど、 " " で囲っちゃダメだと思います。 > ・t2[0]は、なぜundefined? t2[0]に何も代入していないのだから当たり前です。 > ・t2は、連想配列/オブジェクトの何れでしょうか? t2は配列オブジェクトです。 > ・挙動から推測するとオブジェクトっぽいのですが、外側のかっこが[]でもオブジェクトなのでしょうか? 配列だってオブジェクトの一種ですよ。 誤解を恐れずにざっくり言うと、Objectにいろんな配列用のメソッドを付加したらArrayになります。 検索したら良さそうな説明見つけたので紹介しておきます。 (連載なので全記事に全部目を通しても良いかも。) JavaScriptのオブジェクトとは:ちゃんと理解してますか - builder by ZDNet Japan http://builder.japan.zdnet.com/script/sp_javascript-kickstart-2007/20365301/ とても”奇妙”なJavaScriptの配列:JavaやCとは違うのだよ - builder by ZDNet Japan http://builder.japan.zdnet.com/script/sp_javascript-kickstart-2007/20366751/
補足
回答ありがとうございました。 分からないことが出てきたので追加で教えてください >t2[0]に何も代入していないのだから当たり前 ・0へ代入してみました → t2[0]='山田'; ・console.log(t2); //["山田", 佐藤: "鈴木"] ・取得できました → console.log(t2[0]); //山田 ・4へ代入してみました → t2[4]='山田'; ・console.log(t2); //[4: "山田", 佐藤: "鈴木"] ・取得できました → console.log(t2[4]); //山田 ■質問 ・「0」へ代入した時と「4」へ代入した時でconsole.log表示が異なるのはなぜでしょうか? ・[0: "山田", 佐藤: "鈴木"]を期待していたのに、["山田", 佐藤: "鈴木"]と表示される ・0には何か特別な意味があるのでしょうか? ・それとも、console.logが単にそうなっているから? ・あまり気にしなくても良い?
お礼
回答ありがとうございました。 >Object と違い、「定義順で反復処理」できますし、「key を追加すれば length に反映」されます ・定義順は当然保障されるものと思い込んでました… >ECMAScript の new Array は数値添字配列(かつオブジェクト型ですし、new Object は key と value を定義できるだけで「配列」としての機能はありません ・なるほど ・ここら辺が頭の中でごっちゃになってました ・説明分かりやすかったです ・勉強になりましたー