- ベストアンサー
JSの変数について
- JSの変数の使い方を学びましょう。
- 変数を使って効率的なコードを書きましょう。
- 変数のスコープに注意しましょう。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
>回答No.2 amanojaku1 >ifブロックが (ブロックの構造的に)そのイベントリスナーに対応するとイメージして下さい(当然ifブロックとかならイベントで起動する訳ではないので現実的に このような場面は良く有ります)。 実際にはforループなどで そのような場面が多いです。 下記の場合、forループを抜けると変数「i」は消失し、変数「i」でカウントした値はforループ外では使えなくなってしまいます。 j = 0; for(let i = 1; j<=10; i++){ j = i+j; alert( 'i='+i+'; '+ 'j='+j+'; '+ ''); }
その他の回答 (2)
- amanojaku1
- ベストアンサー率54% (265/488)
>>et speed = speedBase; >>let setClickItem1 = setInterval(() => { >>let mathRandom = Math.random(); >>}, speed); >>// ←ここで色々処理が有ったとして。 >>speedBase = speedBase * 0.9; // イベントリスナー内の最後に記述する。 >これはとても良いアイデアですね。思いつきませんでした。 >一度目は減らさなくて良いので減らさずに使って、 >最後に減らし次の回はすでに減っている値を使えば二度目からのみ減らすことが可能なのですね。 >順番を変えるだけでこんなことができるんですね。 処理の順番によって動作が変わってくるので、ソースは ある程度の塊(かたまり)で出して頂かないと、話がウマく伝わらないです(今回も これだけ やりとりして ようやく伝わりました)。 >global >{ >let a = 1; > >イベントリスナー{ >a = 1; >} > >} > >のようにグローバルではないが一つ上、親のスコープに宣言した変数はどうなのでしょうか? >恐らくグローバルだけが例外的にイベントリスナーが終了しても変数が残り続けるので、 >グローバル以外は残らないのでしょうね。 例えばローカル変数「a」が何らかのブロック(if文とか、ループとか、関数とか)で宣言(定義)されているとします。 イベントリスナーが終了しても、その(ローカル変数「a」が宣言(定義)されている)ブロックが終了してなければローカル変数「a」は有効です、そのブロックが終了すれば「a」は消失します(ただし これは あくまでも論理的な話です、イベントリスナーはイベントで起動するので、現実的に そのような場面があるかチョット疑問です)。 もう1度下記を見て下さい。 ifブロックが (ブロックの構造的に)そのイベントリスナーに対応するとイメージして下さい(当然ifブロックとかならイベントで起動する訳ではないので現実的に このような場面は良く有ります)。 ifブロックが終了したら、当然ローカル変数「d」は消失しますが、関数「abc」が終了してなければローカル変数「c」は有効です。 関数「abc」が終了したら、当然ローカル変数「c」は消失します。 >「変数、関数」にはスコープ(有効範囲)と言うモノがあります。 >下記プログラムで説明すると(「変数」はスクリプトがインタプリタに実行されてから「変数」が有効になります)。 >関数abcのスコープ(有効範囲)はグローバル。 >関数内関数bcdのスコープ(有効範囲)は関数abc内。 >変数aのスコープ(有効範囲)はグローバル。 >(引数bはabc関数内だけでなく関数外部との接点も持ってますが)ざっくりと言うと引数bのスコープ(有効範囲)はabc関数内。 >変数cのスコープ(有効範囲)はabc関数内。 >(引数eはbcd関数内だけでなく関数外部との接点も持ってますが)ざっくりと言うと引数eのスコープ(有効範囲)はbcd関数内。 >変数dのスコープ(有効範囲)はifブロック内。 > >a = 3; // 「var」を省略したグローバル変数の初期設定(グローバル変数の場合は こちらの方が便利です)。 >abc(a); >bcd(15); // エラーになる。 >function abc(b){ >let c = 3; >function bcd(e){ >alert('function bcd( ) : e = '+e); >} >if(b==c){ >let d = 4; >alert('function abc( ) : d = '+d); >} >alert('function abc( ) : d = '+d); // エラーになる。 >bcd(5); >}
- amanojaku1
- ベストアンサー率54% (265/488)
>グローバルの領域でvarを省略して代入をすると、同じ名前の変数がグローバルにない場合、代入ではなくvarの省略した >変数の宣言になるのですね。 その辺のカッチリした正式な仕様は知りませんが、(ざっくりと言うと)暗黙の宣言みたいな感じで良いんじゃないでしょうか(正式な仕様と言う意味ではなく、あくまでも雰囲気としてです)。 >一つ目は代入でなく省略した宣言になりますが、二つ目はどうなるのですか? その変数が すでに出現している場合(二つ目)は、代入ですね。 >やはりグローバルにした時のみイベントリスナーが終わってもその中で宣言された変数は残り続けるのですね。 >これは上のスコープであれば参照できるとは違うのですか? >参照はグローバルはもちろんどのスコープからでも参照できますがグローバルでない上にあるスコープなら >参照できますが、こちらはグローバル限定なのでしょうか? すみません、「グローバルでない上にあるスコープ」意味がチョット分からないのですが…。 >let speed = (speedBase = speedBase * 0.9); >let setClickItem1 = setInterval(() => { >let mathRandom = Math.random(); >}, speed); ↑この場合、初期値の値が使えないですが、問題ないですか?、「speedBase = 2000」とした場合、1回目のクリックで「speedに1800が代入」されます。 もし1回目のクリックで初期値の値を使いたいのなら 下記のようになります。 let speed = speedBase; let setClickItem1 = setInterval(() => { let mathRandom = Math.random(); }, speed); // ←ここで色々処理が有ったとして。 speedBase = speedBase * 0.9; // イベントリスナー内の最後に記述する。 >第二引数にspeedBaseという変数名であるとおかしいのでわざわざspeed変数に再代入しないといけない点です。 すみません、意味がチョット分かりにくいですが、とりあえず こちらの認識で説明します。 「speed」ローカル変数自体をグローバル変数にするか、「speed」ローカル変数は使わずに「speedBase」グローバル変数だけにするかの、どちらかになります。 下記は「speed」ローカル変数自体をグローバル変数にした場合の例です。 // グローバル宣言 var speed = 2000; // イベントリスナー内の記述 let setClickItem1 = setInterval(() => { let mathRandom = Math.random(); }, speed); // ←ここで色々処理が有ったとして。 speed = speed * 0.9; // イベントリスナー内の最後に記述する。
お礼
>>> >グローバルの領域でvarを省略して代入をすると、同じ名前の変数がグローバルにない場合、代入ではなくvarの省略した >変数の宣言になるのですね。 その辺のカッチリした正式な仕様は知りませんが、(ざっくりと言うと)暗黙の宣言みたいな感じで良いんじゃないでしょうか(正式な仕様と言う意味ではなく、あくまでも雰囲気としてです)。 >一つ目は代入でなく省略した宣言になりますが、二つ目はどうなるのですか? その変数が すでに出現している場合(二つ目)は、代入ですね。 一つ目はグローバルではvarがなくても代入ではなくvar省略の変数宣言になり、 同じ変数名がある二つ目の場合はグローバルでも代入になるのですね。 >>> すみません、「グローバルでない上にあるスコープ」意味がチョット分からないのですが…。 global { let a = 1; イベントリスナー{ a = 1; } } のようにグローバルではないが一つ上、親のスコープに宣言した変数はどうなのでしょうか? 恐らくグローバルだけが例外的にイベントリスナーが終了しても変数が残り続けるので、 グローバル以外は残らないのでしょうね。 >>> let speed = speedBase; let setClickItem1 = setInterval(() => { let mathRandom = Math.random(); }, speed); // ←ここで色々処理が有ったとして。 speedBase = speedBase * 0.9; // イベントリスナー内の最後に記述する。 これはとても良いアイデアですね。思いつきませんでした。 一度目は減らさなくて良いので減らさずに使って、 最後に減らし次の回はすでに減っている値を使えば二度目からのみ減らすことが可能なのですね。 順番を変えるだけでこんなことができるんですね。 >>> わかりにくくてすいません。 第二引数とは下記のspeedの部分のことです・ let speed = speedBase; let setClickItem1 = setInterval(() => { let mathRandom = Math.random(); }, speed); このspeed変数はこのスピードで繰り返し実行するようにするための秒数なので、 ここがspeedBaseという変数名だとおかしいですよね。 変数名としておかしいという意味です。 例えば中身1なら1秒ごとに繰り返せになるので、 その1が入っている変数はspeedBaseよりspeedの方が正しいと思うという事です。 Baseはあくまで0..9×前の基準の秒数なので。