1. Home
  2. Archive
  3. javascriptの参照渡し

javascriptの参照渡し

今日仕事でjavascriptのカレンダーをいじる機会がありました。ソースはかなり短いものだったのですが、ちょっと変数の受け渡しのところではまってしまいました。

僕が頼まれたのは、月の終わりの日付がうまく終わらないから修正してくれ。という依頼でした。 見てみると全部の月31日までいってますね。こりゃあかん。それで原因を調べてみました。google先生に教えを乞いながら調べること小一時間。原因を突き止めました。どうやらjavascriptのオブジェクトと配列の代入は参照渡しになるという仕様があるらしく、そのせいでうまく動いていなかったようです。参照渡しについては真夜中のプログラミングTipsさんでいろいろと実験をやっていたので参考にさせていただきました。もとの悪い見本のプログラムは下記です。(一部を抜粋)

dateobj = new Date();
drawCalendar(dateobj);
function(){
~省略~
  work = dateobj;
  for (i=1; i<=31; i++) {
    work.setDate(i);
    if (work.getMonth() != dateobj.getMonth())
      break;
    if (work.getDay() % 7 == 0)
      text += '<tr>';
    text += '<td><a href="/timet/?time='+ (work.getTime() / 1000) + '">'+i+'</td>\n';
    if (work.getDay() % 7 == 6)
      text += '</tr>';
    }
  }
}

dateobjが日付オブジェクトなのですが、これをworkにコピーしてforの中でsetDate(i)として一日づつ増やしています。終了条件は(work.getMonth() != dateobj.getMonth())です。つまりiの値がその月の最後より大きい値が入ると終了になります。ここで、オブジェクトは参照渡しになるのでwork.setDate(i);とするとdateobjの内容も一緒に変わってしまうのです。つまりwork.getMonth()とdateobj.getMonth()はいつまで経っても同じ値になるわけですね。今回は下記のようにすることで対応しました。(一部を抜粋)

dateobj = new Date();
drawCalendar(dateobj);
function(){
~省略~
  work = dateobj;
  nowMonth = dateobj.getMonth();
  for (i=1; i<=31; i++) {
    work.setDate(i);
    if (work.getMonth() != nowMonth)
      break;
    if (work.getDay() % 7 == 0)
      text += ‘<tr>’;
    text += ‘<td><a href=”/timet/?time=’+ (work.getTime() / 1000) + ‘”>’+i+’</td>\n’;
    if (work.getDay() % 7 == 6)
      text += ‘</tr>’;
    }
  }
}

変更したのは赤い部分です。オブジェクトか配列以外のデータで代入すればいいので、dateobj.getMonth()をnowMonthに入れて終了判定をnowMonthでやってるわけです。まだいろいろと手を加える必要はあるんですが、とりあえずまともに動作するようになりました。よかったよかった。

トラックバックURL

http://webtech-walker.com/archive/2007/02/27224751.html/trackback

※トラックバックを受け付けてから表示するまでにしばらく時間がかかる場合があります。

コメントフォーム

※HTMLタグは使用できません。