グローバル変数を使用せずに他の関数から変数にアクセスする
-
03-07-2019 - |
質問
さまざまな場所から、グローバル変数は本質的に厄介で邪悪であると聞いていますが、オブジェクト指向ではないJavascriptを実行すると、それらを回避する方法がわかりません。乱数やものを使用した複雑なアルゴリズムを使用して数値を生成する関数がありますが、コールバックなどの別の関数でその特定の数値を使用し続ける必要があるため、同じ関数に含めることはできません。
最初に生成された数値がローカル変数である場合、そこからアクセスできません。関数がオブジェクトメソッドである場合、数値をプロパティにすることができますが、そうではなく、プログラム構造全体を変更してこれを行うのはやや複雑すぎるようです。グローバル変数は本当に悪いのですか?
解決
関数Aで計算された変数を関数Bで表示するには、3つの選択肢があります。
- グローバル化する
- オブジェクトプロパティにする、または
- AからBを呼び出すときにパラメーターとして渡します。
プログラムがかなり小さい場合、グローバルはそれほど悪くありません。それ以外の場合は、3番目の方法の使用を検討します。
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
他のヒント
ここでの最善策は、単一グローバルスコープの変数を定義し、そこに変数をダンプすることです。
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
上記のようなことをすることに対して誰もあなたに怒鳴るべきではありません。
名前空間の使用を検討する:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
local_function
と global_function
の両方が、すべてのローカル変数とグローバル変数にアクセスできます。
編集:別の一般的なパターン:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
return
edプロパティは、名前空間オブジェクトを介してアクセスできるようになりました。 ns.foo
、ただしローカル定義へのアクセスは保持しています。
探しているものは、技術的にはカレーとして知られています。
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
上記は正確にカリー化された関数ではありませんが、グローバル名前空間に変数を追加したり、他のオブジェクトリポジトリを必要とせずに既存の値を維持した結果を達成します。
別の関数が変数を使用する必要がある場合、引数として関数に渡します。
また、グローバル変数は本質的に厄介でも悪でもありません。それらが適切に使用されている限り、それらに問題はありません。
このコードを再利用する可能性がある場合は、おそらくオブジェクト指向の観点で取り組むよう努力するでしょう。グローバル名前空間の使用は危険な場合があります。再利用される変数名が原因でバグを見つけるのが難しいというリスクがあります。通常は、単純なコールバック以外の目的でオブジェクト指向のアプローチを使用することから開始するため、書き直しを行う必要はありません。 javascriptに関連する関数のグループがあるときはいつでも、オブジェクト指向アプローチの候補になると思います。
別のアプローチは、Douglas Crockfordフォーラムの投稿( httpから選んだものです。 ://bytes.com/topic/javascript/answers/512361-array-objects )。ここにあります...
ダグラス・クロックフォードはこう書いています:
2006年7月15日
" IDでオブジェクトを取得する場合は、オブジェクトではなくオブジェクトを使用する必要があります アレイ。関数はオブジェクトでもあるため、メンバーを 関数自体。"
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"オブジェクトは次の方法で取得できます
objFacility.wlevine
オブジェクトのプロパティは、他の関数内からアクセスできるようになりました。
元の質問に関連して、これが非常に役立つことがわかりました。
functionOneで使用する値を返し、functionTwo内でfunctionOneを呼び出し、結果を新しい変数に配置し、この新しい変数をfunctionTwo内で参照します。これにより、functionTwo内でfunctionOneで宣言されたvarを使用できるようになります。
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
私はあなたの問題の詳細を知りませんが、関数が値を必要とするなら、それは呼び出しを通して渡されたパラメータである可能性があります。
グローバルは悪いと見なされます。グローバル状態と複数の修飾子が、追跡が困難なコードや奇妙なエラーを作成する可能性があるためです。何かをいじる多くの俳優にとって、混乱が生じる可能性があります。
カスタムjQueryイベントを使用して、javascript関数の実行を完全に制御(およびそれらの間で変数を渡す)することができます。 (ajax呼び出しを使用しても)。
答えは次のとおりです(重要:チェックされた答えではなく、私による「Emile」という答えです):