memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

JSの配列の面白い使い方

本学科の3年次の少人数授業がありまして、数年前よりenchant.jsを利用してスマホゲームを作る授業を進めています。

学生さんが講師となり能動的(いわゆるアクティブラーニング)に学んでいます。

enchant.jsが改訂されたため、今年から教科書を以下のものに変更しました。

はじめて学ぶ enchant.jsゲーム開発

はじめて学ぶ enchant.jsゲーム開発

で、本日も授業だったのですが、今回のプログラムはなかなか面白いものでした。

一部、サンプルプログラムを掲載します。かなり省略しています。

var switches = [];
for (var j = 0; j < f ; j++) {
  var c =  Questions[no][j].length;
  for (var i = 0; i < c ; i++) {
    var sw = new Switch(i*32+32, j*32+32);
    switches[[i, j]] = sw;
  }
}

面白いと思ったのは(というか私は初めてみたのですが)、”switches[ [i, j] ]”の部分です。

switchesは配列変数ですが、その要素の指定が配列(配列リテラルなのかなぁ?)です。これはどう解釈すればいいのでしょうか?

やりたいことはわかります。switchesという一次元配列?に二次元のようなインデックスで指定して値を代入&取り出ししたい。

パーフェクトJavascipriptなど手元にあったJS本をあれこれひっくり返してみましたがわかりませんでした。

Webインスペクターで少し実験してみますと、

a = []
a[[1,1]] = 1
a[[1,1]]
→1
a
→[]

とすると確かにa[ [1,1] ]には1が代入されています。aそのものを表示してみると配列は空です。当然、サイズも0です。どういうことでしょうか?不思議です。。。仕様の理解が浅いのですね。。。

ちなみに、[1,1]と[1,1]を比較してみると両方ともfalseでした。ということは[1,1]は配列リテラルではない?というか配列リテラルって比較できるのか?

[1,1] == [1,1]false
[1,1] === [1,1]false

ちなみにRubyで[1,1] == [1,1]をやってみるとtrueでした。JSのオブジェクトの内容をインスペクションする方法を知らないのでわからなのですが、JSの[1,1]はobjectであるなら、C言語のアドレス、もしくはRubyのobject_idのようにインスタンス毎に異なる数値が返ってくるのではないかと想像します。あくまで想像です。

ちなみにこのプログラムには続きがあって、選択した駒の上下左右を検査するプログラムがあります。そこで、検査する位置をコード内で作り出して(★部)、keysの要素数分まわして検査します。イディオムなんでしょうね。。。これは面白い。

var keys = [[r - 1, c], [r + 1, c], [r, c - 1], [r, c + 1]]; //★
for (var i in keys) {
  var sw = switches[keys[i]];
  if (sw) {
      //なんらかの処理
  }
}

もし上記について仕様をご存知の方でお時間が許す方がいらっしゃいましたらお教えいただけると幸いです。