二次元の連想配列に対してデータを追加してもundefinedと表示されてしまいます
JavaScript(以下JS)に連想配列なんてありませんけど?
というわけで解説。
これはPHPを普段メインに使っており、JSをサブで扱っているエンジニアに陥りがちなミスです。
PHPとJSの違いとは?
PHPはどんな形式で配列を作っても内部的にはハッシュマップを使った連想配列という扱いになります。
(PHP7では速度を稼ぐ為に裏で本物の配列を用意するようになりましたが、PHP5.6までは全てハッシュマップの連想配列ですし、表面上は7になっても全て連想配列です)
JSには配列とオブジェクトの2つが存在します。
この配列とオブジェクトにFirefox作ってる団体が管理しているMDNというサイトのリンクを張りましたのでそちらを確認してほしいのですが、所持しているプロパティやメソッドが全くと言って良いほど違うことがわかります。
因みに[1, 2, 3].push(value)
みたいな感じで使うメソッドは、
Array.prototype.push
という風にJSのプロトタイプ拡張という機能を使って実装されたメソッドを指します。
JavaScript
1data= [
2 {
3 data1:"test" ,
4 somedata: {
5 a: "hogeA",
6 b: "hogeB"
7 } ,
8 data2:"test2"
9 }
10]
11data[0].somedata.push("hogeC");
12// VM78:1 Uncaught TypeError: data[0].somedata.push is not a function
13// at <anonymous>:1:18
JSではこれをオブジェクトの配列と呼びます。
あくまで配列自体は一次元。
そこからハッシュマップ的な使い方をしているオブジェクトを並べていると表現します。
somedataに値を追加しようとpushメソッドを実行しましたが、「お前は関数じゃないだろ」エラーが出てしまいました。
これはsomedataはキーと値のセットを表現するためにオブジェクトで作りましたが、
配列とは違ってpushメソッドがないことから生じるエラーになっています。
オブジェクトへのキーの追加は代入式で行います。
配列もそれで出来ますが、配列は末尾に追加するならpushを使った方が自然でしょう。
JavaScript
1data= [
2 {
3 data1:"test" ,
4 somedata: {
5 a: "hogeA",
6 b: "hogeB"
7 } ,
8 data2:"test2"
9 }
10]
11
12data[0].somedata.c = "hogeC";
13// プロパティに変数名や可変文字列でアクセスしたいなら[]を使う
14data[0].somedata["d"] = "hogeD";
15
16console.log(data);
17// [
18// {
19// "data1": "test",
20// "somedata": {
21// "a": "hogeA",
22// "b": "hogeB",
23// "c": "hogeC",
24// "d": "hogeD"
25// },
26// "data2": "test2"
27// }
28// ]