こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

javascript 関数についての質問

javascriptで
入力された日付を元に30日後、40日後、60日後、90日後の日付を表示したいのですが、
作った関数が1回しか使えませんTT(?)何回も使えるようにしたいです!
初歩的な質問ですみませんが、どうすればよいでしょうか?


<html>
<head>
<title>ねこ</title>
<script>
function Kekka(days){
Yobi = new Array("日","月","火","水","木","金","土");

Date = new Date(document.form.y.value,
document.form.m.value -1,
document.form.d.value);

d = Date.getDate();

Date.setDate(d+days);

y = Date.getFullYear();
m = Date.getMonth()+1;
d = Date.getDate();
w = Date.getDay();

str1 = y+"年"+m+"月"+d+"日("+Yobi[w]+"曜日)";

//土曜日か日曜日だったら次の月曜の日付もとる
if(w == 0){
w = 1;
Date.setDate(d+days+1);
d = Date.getDate();
}
else if(w == 6){
w = 1;
Date.setDate(d+days+2);
d = Date.getDate();
}
str2 = y+"年"+m+"月"+d+"日("+Yobi[w]+"曜日)";

return str1,str2;
}
function CLR(){
document.form.y.value="";document.form.m.value="";document.form.d.value="";
document.form.v1.value="";document.form.v1_2.value="";
document.form.v2.value="";document.form.v2_2.value="";
document.form.v3.value="";document.form.v3_2.value="";
document.form.v4.value="";document.form.v4_2.value="";
document.form.v5.value="";document.form.v5_2.value="";
}
function Test(){
Kekka(30);
document.form.v1.value = str1;
document.form.v1_2.value = str2;

Kekka(40);
document.form.v2.value = str1;
document.form.v2_2.value = str2;
}

</script>
</head>
<body>
てすとなう<br><br>

<form name="form">
<input type="text" name="y" size="4">年
<input type="text" name="m" size="2">月
<input type="text" name="d" size="2">日

<input type="button" value="start" onclick="Test()">
<input type="button" value="CLR" onclick="CLR()">
<br><br>

30日後:<input type="text" name="v1" size="27">→<input type="text" name="v1_2" size="27"><br>
40日後:<input type="text" name="v2" size="27">→<input type="text" name="v2_2" size="27"><br>
60日後:<input type="text" name="v3" size="27">→<input type="text" name="v3_2" size="27"><br>
90日後:<input type="text" name="v4" size="27">→<input type="text" name="v4_2" size="27"><br>
3ヶ月後:<input type="text" name="v5" size="27">→<input type="text" name="v5_2" size="27"><br>
<br><br>
</form>

</body>
</html>

投稿日時 - 2012-10-14 05:22:00

QNo.7747555

困ってます

質問者が選んだベストアンサー

これがダメなのでは?
Date = new Date(document.form.y.value,
document.form.m.value -1,
document.form.d.value);
Dateを上書きして、元のDateを破壊しています。

大文字のDateだとシステムのDateを破壊してしまうので例えば、小文字のdateを使ってみてはいかがでしょうか?
date = new Date(document.form.y.value,
document.form.m.value -1,
document.form.d.value);
当然、これ以降に出てくるDateはdateに書き換えてください。
d = date.getDate();
のような感じです。

あと、変数を最初に使うときはvarをつけてちゃんと宣言したほうがいいですね。こうやって変数が使える範囲(スコープと言いますが)を制限します。
var date = new Date(document.form.y.value,
document.form.m.value -1,
document.form.d.value);
var d = date.getDate();
のような感じで。
関数の中で変数を使うときにvarで宣言しておくと関数の外からそれが見えなくなるので、多少破壊的なことを関数でやってもその影響を外に及ぼさなくなります。プログラムのどこからでも参照できるグローバル変数は便利で、その弊害を誰も教えてくれないので初心者はついつい使ってしまいますが、局所性が保証されなくなるので必要な場合を除いては使わないほうがいいです。
関数内でvarを使う場合、関数の外からその値が見えなくなるので、関数から値を帰す場合はちゃんとreturnで返して受け取らないと受け取れません。
しかも、JavaScriptは複数の返り値を持てないのでちょっと工夫が必要です。

例えば、
function Kekka(days){
...略...
var str1 = ...
...略...
var str2 = ...
...略...
return Array(str1,str2);
}

としておき、
k = Kekka(30);
document.form.v1.value = k[0];
document.form.v1_2.value = k[1];
と書く方法があります。

あるいは、連想配列を使うこともできます。
function Kekka(days){
...略...
var ret = {}
ret.str1 = ...
...略...
ret.str2 = ...
...略...
return ret;
}
としておき、
k = Kekka(30);
document.form.v1.value = k.str1;
document.form.v1_2.value = k.str2;
という感じです。

あとは、日付に変換するところもtoLocaleString()でよいならわざわざ各必要ないかと...strftimeがないのが良くないとは思いますが。


というわけで、Dateを破壊していたのを修正しましょう。
また、可能ならばvarを使って変数のスコープを関数内に制限しましょう。

投稿日時 - 2012-10-14 10:08:22

お礼

ありがとうございます!
Dateを破壊していた→予約語みたいなものを使っていた?
とにかく正常に動作するようになりました。

他の指摘についても、参考になります。TT
丁寧な解説ありがとうございます。

回答を参考にさせていただいて、
これから精進していきたいと思います!

投稿日時 - 2012-10-14 12:14:51

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

Date = new Date(document.form.y.value, ……

これが原因ですね。Dateオブジェクトを上書きしてしまっているので、次にnew Dateしたときには前回作成したオブジェクトがDateに設定されており、Dateコンストラクタ関数ではなくなってしまってます。なので、Dateという変数名を変えてください。

投稿日時 - 2012-10-14 10:14:09

お礼

回答ありがとうございます。!
わかりやすく、勉強になりました!。

投稿日時 - 2012-10-14 12:20:22

あなたにオススメの質問