Hatena::ブログ(Diary)

IT戦記 このページをアンテナに追加 RSSフィード Twitter

2007-02-02

JavaScript の配列と連想配列の違い

id:cheesepie:20070131:1170172709

最近は、こういう風に JavaScript を勉強する人が増えていてとても嬉しいです ^^ id:cheesepie さん頑張ってください!

で、ちょっと配列と連想配列の使いかたが違うようなので、エントリーを書こうと思いました。おせっかいだったらすみません>< ! やっぱり、このへんが JavaScript の難しいところのひとつなのだろうか。

ということで、 JavaScript配列と連想配列の違い

いってみよおー

連想配列とは

JavaScript では連想配列は一番シンプルなオブジェクトのことである。つまり、すべてのオブジェクトは連想配列である。

以下のすべての連想配列はまったく同じものである。

// 1
var obj = { hoge: 'hoge' };

// 2
var obj = { 'hoge': 'hoge' };

// 3
var obj = {};
obj.hoge = 'hoge';

// 4
var obj = {};
obj['hoge'] = 'hoge';

// 5
var obj = new Object();
obj.hoge = 'hoge';

この hoge のように連想配列のキーになるシンボルのことをプロパティという


配列とは

配列プロトタイプ継承したオブジェクトのことである。

以下のすべては同じ配列である。

// 1
var array = ['hoge', 'fuga'];

// 2
var array = new Array('hoge', 'fuga');

// 3
var array = Array('hoge', 'fuga');

// 4
var array = [];
array[0] = 'hoge';
array[1] = 'fuga';

// 5
var array = [];
array['0'] = 'hoge'
array['1'] = 'hoge'

// 6
var array = { 0: 'hoge', 1: 'fuga', length: 2 };
array.__proto__ = Array.prototype;

6 の例が分かれば、 JavaScript配列は分かったも同然である。


走査のしかた

for in配列走査のための記法ではない

for in配列の走査の目的では使ってはいけない。たとえば、以下のようにプロトタイプが拡張された場合に対応出来なくなってしまう。

Array.prototype.hoge = function() {};

for (var i in ['a', 'b', 'c']) {
  alert(i); // 1, 2, 3, hoge が表示される
}

for inオブジェクトプロパティを走査する記法だからだ。

では、 length プロパティは何故走査されないか。それは、 length が特別な DontEnum プロパティだからだ。基本すべてのプロパティは走査される。

配列は素直に for
var array = ['hoge', 'fuga'];

for (var i = 0; i < array.length; i ++) {
  alert(array[i]);
}
連想配列には for in
var hash = { hoge: 'hoge', fuga: 'fuga' }

for (var i in hash) {
  alert(hash[i]);
}

こんな感じでどうでしょう。

以上、おせっかいエントリーでした><

PiroPiro 2007/02/02 13:24 JavaScript 1.6のforEachとかsomeとかeveryとかもよろしく。と言ってみるテスト。

amachangamachang 2007/02/02 13:28 そうですね!ありがとうございます! IE に forEach が欲しいですね。最近ちょっとだけ XUL をやるので forEach は使うようになりました!

tohokuaikitohokuaiki 2007/02/02 17:28 PHPからプログラム始めた私にはJavaScriptの配列と連想配列の違いが分かりにくかったので、大変ありがたいエントリでした。

cheesepiecheesepie 2007/02/02 18:05 おせっかいだなんてとんでもないです!とても勉強になりました。ありがとうございます。
obj[’hoge’]なんて書き方も出来るんですね。便利だけど難しい。。。
forとfor inの使い分けも参考になりました。

dambiyoridambiyori 2007/02/03 02:37 すいません。id:cheesepieさんのコメント欄で、「大きなデータはプロトタイプに持ったほうがいいと思います」と書かれていますが、どういった利点があるのでしょうか。先日まさに大きなデータを変数に突っ込むプログラムを書いたので、ちょっと気になりました。よろしくお願いします。

arisuarisu 2007/02/05 21:14 質問なのですが6の例も配列らしいですが
6の例に例えば
array[3]=’piyo’;
alert(array.length)
とやっても私の期待通りにならない為うまく理解が出来ません。
配列ってのはとにかく配列プロトタイプを継承すれば配列なんですか?

arisuarisu 2007/02/05 21:15 ごめんなさい
array[2]=’piyo’;
が適切ですね

amachangamachang 2007/02/05 22:49 そうですね。厳密には 6 の例と [’hoge’, ’fuga’] は違うようですね。混乱させてしまってもうしわけありません。

オブジェクトのプロパティの状態が同じというだけで、 length をオートインクリメントする性質は受け継がれないです。

array.push(’piyo’); alert(array.length);

としてみてください。

arisuarisu 2007/02/05 23:04 返答有難うございます。
pushをしてみたのですがIEに怒られました。
Arrayのプロパティしか受け継がないって事の証明みたいなもんなのでしょうか。
多分私がprototypeというかJavaScriptのobjectの理解が私に出来てないようですね。
こういう系の解説のある良い本が見当たらないので困ってますがもうちょっと勉強してみますね。

amachangamachang 2007/02/05 23:37 __proto__ 自体が IE では実装されていません。Firefox でやってみてください。

dambiyoridambiyori 2007/02/06 00:46 申し訳ありません。id:cheesepieさんのプログラム改めて見直したら、物凄くボケた事を質問したことに気づきました。本当にどうもすいません。

am11opam11op 2007/02/12 02:40 こんにちは。
> for in は配列走査のための記法ではない
Object は汚染するものだってことですよね、きっと。
勝手に勇気をもらいました。

kenbookenboo 2008/01/25 07:26 このエントリーのおかげで、仕事がすすみました。
ブックマークさせていただきました。
ありがとうございます!!

shinriyoshinriyo 2011/12/19 13:21 参考になりました。
以下で0と1と2のアラートでびっくりしてました。
var nums = '3,6,8';
var numAry = nums.split(",");

for (var i in numAry){
alert(i);
}

tokuhiromtokuhirom 2012/09/01 17:57 ふとtwitterでみかけてよんだんですが、ES5の時代にみると、ちょっと違和感があるエントリになってますねー(5年たってるからしょうがないですけどw)。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。

トラックバック - http://d.hatena.ne.jp/amachang/20070202/1170386546