- ベストアンサー
スコープ内の処理終了次第変数の中身が捨てられる
- スコープ内の処理終了次第変数の中身が捨てられ、グローバルで宣言すると管理が離れてしまう問題について質問しています。
- グローバルで宣言すると変数がリロードするまで残るので、管理が困難です。
- スコープ内で変数を残すことができれば解決するのか疑問を持っています。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
> オブジェクトの呼び出しも大カッコなのは何故なんですかね? 参考にされたページでどう説明されているのかは、把握してませんので 詳しくはそちらを参考にされて下さい。 一般的には、 ・一行で複数の要素を代入するなら 「変数名 = { }」 。 ・1つの要素へ代入したり、値の取り出しをするなら、「 変数名[キー ] 」 です。 つまり、 hoge = { ' フー ' : 'foo' , 'バー ' : 'bar' , ' ピヨ ' : 'piyo' }; は前者 hoge [ 'フー' ] = 'foo'; hoge [ 'バー' ] = 'bar'; hoge [ 'ピヨ' ] = 'piyo'; xxxx = hoge[ 'フー' ]; console.log( hoge[ 'ピヨ' ] ); が後者 です。
その他の回答 (6)
- superside0
- ベストアンサー率64% (461/711)
> 変数や配列は中身が捨てられないようにするには宣言をグローバルで行うしかないが > オブジェクト(連想配列ともいう?)であればこれらと違って、なぜか? > ローカルに宣言しても中身はずっと捨てられずに残っているので、フラグなど処理が > 終わった後も残しておきたい情報は、配列、変数ではなく、あえてオブジェクトにす る。 > という事でしょうか? いやいや、 変数、配列、連想配列、オブジェクトのどれも、スコープの扱いは同じです。 つまり、関数を抜けたあとも関数内で作った値を保持させたいなら、 連想配列でも配列でもオブジェクトでも、ローカル宣言すると捨てれるのは変数と同じなので、 捨てられないようにするには、いずれにせよグローバル宣言にする必要があります。 (もしくは return値にして、その結果を利用箇所のスコープ内で参照できる 変数への代入にするかですが、今回は関係ないので省略します) しかし、 変数を使うと、変数では1つの値しか管理できないので、 4つの異なるフラグの用途が必要であれば、4つのグローバル変数が必要となりますが ここが異なるのです。 つまり、フラグ用の変数を グローバル宣言する部分で、変数でなく 連想配列(配列でもオブジェクトでも同じですが)で宣言しておけば 1つで複数の値を扱えるので、 フラグが沢山必要なときでも、1回のグローバル宣言だけですみますよ、ということです。 (これが このご質問の本題で、No1の件です) 言葉では分かり難いかもしれないので、 例えば、ボタンがonclickされたときに、一旦フラグだけセットしておいて submit時にそのボタンに対応したHidden値を空にするというJSがあったとします。 そのボタンが100個必要になったときの例ですが、 普通の変数だけで書いてあると var data_use1 = false; var data_use2 = false; var data_use3 = false; .....(以下data_use100まで繰り返し) function set_flag1 () { //onclickで呼ばれて、フラグのみセット data_use1 = true; } function set_flag2() { data_use2 = true; } ...(以下~set_flag100 まで繰り返し).... function submit_form() { //フラグ利用部 if ( data_use1 == true ) document.getElemetById('data_use1').value = ''; if ( data_use2 == true ) document.getElemetById('data_use2').value = ''; ..(以下100 まで繰り返し)... } とこのように、大量なコーディングが必要となりますが、 ※実際には、”(繰り返し)”とあるところは100回記述しないといけないので。 しかし、これを連想配列 (配列やオブジェクトのメンバ変数でも考え方は同じ) を 使うと、上記を同じことを var flag= []; //グローバル宣言は1つだけ function set_flag(name) { flag[name] = true; //フラグ値をセットする関数も共通化できるので1つだけ } function submit_form() { //フラグの利用部も キーにIDを使うなど工夫しておけば、共通化が可能 for ( key in flag ) { if ( flag[key] == true ) document.getElementById(key).value = ''; } } と記述するだけですむことになります。
お礼
やはりグローバルに置かない限りそのスコープの処理が終われば中身も破棄される事はオブジェクトも同じなのですね。 グローバルに置かざるおえないのは使用上絶対にさけられないのですね
補足
オブジェクトの呼び出しも大カッコなのは何故なんですかね?
- superside0
- ベストアンサー率64% (461/711)
> 連想配列というもの自体がないので、オブジェクトといってもらった方がわかりやす いです。 flag.xxxx = 'aaa' のように使うのなら、オブジェクトと呼んだほうが通じやすいですし flag.['xxxx'] ='aaa'; のように使うなら連想配列と呼んだほうが一般的には通じやすい と思いますよ。 #JSでの連想配列の使い方を説明しているWebページは沢山あるので、参考にされてはどうでしょう。 > 変数をたくさん作らずにまとめられるというのが唯一のメリットでしょうか? もともと”配列”というものを ご存知でなければ、そういうことになります。 ただ、配列は知っているけど、連想配列はご存知でないということなら これのメリットは、前述したとおりで、配列のキーに文字列が使えるという点です。 (これはかなり応用できる用途があります) なお、その応用の一部として、フラグごとの用途をキーにすることで フラグ用の変数をいちいちグローバル変数で宣言をしないで済みますので そういう使い方もあります、というのがNo.1の内容です。 (ここまでは、すべてNo1の補足ということになります)
お礼
下記の大かっこが配列でそれを変数に代入している。 var hoge = []; 下記の波かっこがオブジェクトでそれを変数に代入している。 これを他の言語では連想配列という? var hoge = { }; https://blog.codecamp.jp/javascript-array より 宣言と代入をいっぺんにする var hoge = { ‘ フー ' : ‘foo’ , ‘ バー ‘ : ‘bar’ , ‘ ピヨ ‘ : ‘piyo’ }; オブジェクトの値を取得。ただなぜここだけ大かっこになるのでしょうか? hoge [ ‘ フー ‘ ] // foo と表示されます hoge [ ‘ バー ‘ ] // bar と表示されます hoge [ ‘ ピヨ ‘ ] // piyo と表示されます >>> フラグ用の変数をいちいちグローバル変数で宣言をしないで済みますので そういう使い方もあります、というのがNo.1の内容です。 変数や配列は中身が捨てられないようにするには宣言をグローバルで行うしかないがオブジェクト(連想配列ともいう?)であればこれらと違って、なぜか? ローカルに宣言しても中身はずっと捨てられずに残っているので、フラグなど処理が終わった後も残しておきたい情報は、配列、変数ではなく、あえてオブジェクトにする。 という事でしょうか?
- superside0
- ベストアンサー率64% (461/711)
> > function func1() { > flag['key1'] = 'aaa'; // key1(例)というキーは宣言してないのに使える >このような形は初めて見たのですが、関数の中に配列がありそれに文字列を代入しているのですか? 関数の中にあるかどうかは、今は関係ないです。 また、文字列が代入できるかどうかも、関係ないです。 大事なのは、 連想配列だと 配列の位置を指定するのに、数字でなく文字列が使えるという点です。 普通の配列は flag[1] = 'aaa'; flag[2] = 'bbb'; のように配列上の場所を指定するのに整数を使いますが、 連想配列だと flag['xxxxx'] = 'aaa'; flag['yyyy1223zzz'] = 'bbb'; のように任意の文字列(キー)が格納場所の指定に使えます。 forループで順番に処理したり、配列の格納する場所が大事な場合は、通常の配列を使いますが、 名前に対する値を取り出したいといったときには、 この連想配列を使えば、 forループで探さなくても、名前そのものをキーにして一発で値が取り出せるので、楽です。
お礼
結局JSではオブジェクトですよね? 連想配列というもの自体がないので、オブジェクトといってもらった方がわかりやすいです。 flag['xxxxx'] = 'aaa'; こちらはオブジェクトでflagというオブジェクトのキーxxxのバリューにaaaを指定するという事ですよね? 本題に戻りますが、これを使うとどのようなメリットがあるのでしょうか? 結局グローバルにこのオブジェクトを配置しないといけないのですよね? 変数をたくさん作らずにまとめられるというのが唯一のメリットでしょうか?
- superside0
- ベストアンサー率64% (461/711)
> スコープの件は私に認識で正しいのでしょうか? はい。 ローカル変数は、ローカルな変数なのですから、ローカル以外からは参照できません。 > また連想変数というのはJSイモあるのですか? 連想変数でなく、連想配列でした失礼しました。 (ハッシュ変数と書くべきか連想配列と書くべきか迷ってしまって 変な造語を作ってしまいました) > 連想配列ならphpにあるようですが、JSはオブジェクトですよね? ご指摘の通り、JavaScriptの連想配列は、オブジェクトの応用ですね。 ただ、perlやPHPの連想配列っぽく書くことは可能です。 例) var flag = [ ]; //グローバル変数として flag(例)という連想配列を用意(実際はオブジェクト) function func1() { flag['key1'] = 'aaa'; // key1(例)というキーは宣言してないのに使える flag['key2'] = 'bbb'; // key2(例)というキーも同様 //なおオブジェクトなので、flag.key1 ='aaa'; flag.key2 = 'bbb';とも書ける } function test() { func1(); //func1をコールして連想配列に値をセット console.log(flag['key1']); //func1()の外なのに、func1()内のkey1の値の'aaa'が取り出せる console.log(flag['key2']); //同上 //console.log(flag.key1); console.log(flag.key2); でも可能 }
お礼
>>> function func1() { flag['key1'] = 'aaa'; // key1(例)というキーは宣言してないのに使える flag['key2'] = 'bbb'; // key2(例)というキーも同様 //なおオブジェクトなので、flag.key1 ='aaa'; flag.key2 = 'bbb';とも書ける } このような形は初めて見たのですが、関数の中に配列がありそれに文字列を代入しているのですか?
- amanojaku1
- ベストアンサー率54% (265/488)
>グローバルで宣言するとできるのですが グローバル変数でヤルしかないでしょう。 >こんなに離れている管理しにくくないですか? 大きなプログラムになっても(つまり場所が離れても)、自分に分かりやすい変数名を付けて下さい。
お礼
グローバル変数意外はそのスコープから抜けた瞬間に変数の中身が捨てられてしまうのですね。 他に方法が無ければ仕方が無いのでコメントアウトでグローバル変数があると記載するしか無いでしょうか。
補足
下記のようにまとめたのですが、正しいでしょうか? とくにJSは連想配列というものが実質オブジェクトになっているので、 連想配列とはあまり言わないと聞いたのですが、どう思われますか? >>> 下記の大かっこが配列でそれを変数に代入している。 var hoge = []; 下記の波かっこがオブジェクトでそれを変数に代入している。 これを他の言語では連想配列という? var hoge = { }; https://blog.codecamp.jp/javascript-array より 宣言と代入をいっぺんにする var hoge = { ‘ フー ' : ‘foo’ , ‘ バー ‘ : ‘bar’ , ‘ ピヨ ‘ : ‘piyo’ }; オブジェクトの値を取得。ただなぜここだけ大かっこになるのでしょうか? hoge [ ‘ フー ‘ ] // foo と表示されます hoge [ ‘ バー ‘ ] // bar と表示されます hoge [ ‘ ピヨ ‘ ] // piyo と表示されます >>> フラグ用の変数をいちいちグローバル変数で宣言をしないで済みますので そういう使い方もあります、というのがNo.1の内容です。 変数や配列は中身が捨てられないようにするには宣言をグローバルで行うしかないがオブジェクト(連想配列ともいう?)であればこれらと違って、なぜか? ローカルに宣言しても中身はずっと捨てられずに残っているので、フラグなど処理が終わった後も残しておきたい情報は、配列、変数ではなく、あえてオブジェクトにする。 という事でしょうか?
- superside0
- ベストアンサー率64% (461/711)
スコープうんぬんの件は、当然の話ですが、 フラグ変数が必要になるたびに、それをいちいちグローバル変数で宣言するのが面倒ってことなら、 フラグ用の連想変数を1つだけ作っておいて、キーの違いで使い分けては?
お礼
スコープの件は私に認識で正しいのでしょうか?また連想変数というのはJSイモあるのですか? 連想配列ならphpにあるようですが、JSはオブジェクトですよね? 具体的にソースなど見せてもらえばありがたいです。
補足
難しくてさっぱりわかりません。 >>> フラグ用の連想変数を1つだけ作っておいて、キーの違いで使い分けては?
お礼
(オブジェクトは必ず波カッコ と思ったのですが、、配列に一変に値を代入するときは波カッコと言うことですね