2014年06月02日
川俣晶の縁側ソフトウェア技術雑記total 5897 count

超やばい・ネット上にJavaScriptの連想配列の説明が間違っている例が多すぎる

Written By: 川俣 晶連絡先

「バグを調査している途中で、実はかなり危ないことに気づいた」

「なんだい?」

「ネット上のJavaScriptの連想配列の説明が間違っている例が多すぎる」

「間違った例を教えてくれ」

「以下は典型的なよくある間違ったバターンだ」

配列の場合 §

var x = new Array();// またはvar x =[];

x[0] = "b";

x[1] = "d";

alert(x[0]);

alert(x[1]);

連想配列の場合 §

var x = new Array();// またはvar x =[];

x["a"] = "b";

x["c"] = "d";

alert(x["a"]);

alert(x["c"]);

「何が良くないわけ?」

「x["a"] = "b";っていうのは任意のオブジェクトに動的にメンバーを追加しているだけなんだ。そして、配列オブジェクトもオブジェクトだからメンバーを追加できている。しかし、それは配列にメンバーを追加したこととはイコールにならない」

「なぜそれが問題になるわけ?」

「サイズを取得したら一発で分かる。alert(x.length);を追加してみよう」

「あっ! 配列の場合は2になるのに連想配列の場合は0になる」

「そうだ。実はJavaScriptには本当の意味での連想配列は無いんだ。みんなが連想配列と言っているのは、オブジェクトに対する動的なメンバーの追加削除に過ぎない。つまり、配列オブジェクトを使ったとしても、配列としての機能と一切関係無く、動的にメンバーが追加されたり削除されていたりするだけなのだ」

「じゃあ、配列の意味ないじゃん」

「そうだ。だから初期化の際に new Array();や[]を指定するのはまったくの無駄」

「じゃあどう書けばいいの?」

「空のオブジェクトとして{}を書けば良いだけだ」

var x = {};

x["a"] = "b";

x["c"] = "d";

alert(x["a"]);

alert(x["c"]);

「だけどさ、こうしたらlengthが使えなくなっちゃったよ」

「それは配列のメンバーだから当たり前だ。ここではもう配列を使っていないんだ」

「じゃあどうやってサイズを得るわけ?」

「for inでまわして数を取得するしかなかろう」

var length=0;

for (var dummy in x) length++;

alert(length);

「でもさ。配列ならサイズが取得できて当たり前じゃん。これは配列の一種といえるの?」

「言えないよ。だから本当の意味での連想配列はJavaScriptには無いんだよ。連想配列的に使える機能があるだけ」

「じゃあ話を簡単にするためには配列のlength使うのやめて、全部for inで数えていい?」

「それはダメっ! 動的に追加されたメンバーも数えちゃうから本当の配列の個数とは違う数値が出てくる場合があるのっ!」

「ほんとに?」

「以下のように書くと配列のサイズは2だけど、for inループは3回まわっちゃうの!」

var x = [];

x[0] = "b";

x[1] = "d";

x.hello = function () { alert("hello!"); };

var length=0;

for (var i in x) length++;

alert(length);

「素直にalert(x.length);と書けば2が出てくるわけだね」

「それからこういう例もあるからね」

var x = [];

x[0] = "b";

x[2] = "d";

var length=0;

for (var i in x) length++;

alert(length);

alert(x.length);

「あれ、for inは2回しかまわらないのに、x.lengthは3を報告するぞ」

「そうだ。オブジェクトに入っているデータは2個しかないが、添え字は0から2まで存在しているからだ」

感想 §

「泥沼に足を取られた」

「なんで?」

「うっかりネットから取ってきたサンプルソースを改変して書いたらドはまりした」

「分かった。どこにも存在しない【JavaScriptの連想配列】を当てにして扱ってしまったんだね」

「そうだな。ネットの情報嘘ばかりだ」

「日頃からそう言ってる君がはまっていたら世話が無いよ」

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2014年
06月
03日
今日考えた強力なデバッグ手法・"staging debug" (涙)
3days 0 count
total 9539 count
【技術雑記】の前のコンテンツ
2014年
05月
23日
そこはattrではなくpropだっ! 昔の自分に泣く
3days 0 count
total 4827 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

https://mag.autumn.org/tb.aspx/20140602151206
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.