Javascriptにおけるクローズドとスコープ
8052 ワード
JavaScriptのクローズドとスコープ
転載または引用の場合は、出典を宣言してください.
解決する問題は、メソッドAからメソッドBに定義された変数を使用することです.
クローズド:関数生成時に近くの値を取り込むことができる関数です.ソースコードにいくつかの語句を挿入するために追加します. は、add方法を追加し、比較を実行する .では、この関数はいつ生成されましたか?コードには が存在することに留意されたい.新しいテスト 山を越えて山を越えるadd方法はsの道のadd方法を探してsを探す時、B()の方法の中で生成するため、まず探すのはBのありかの作用の領域で、このように(var s=0)を探し当てることができて、1,2,3回その+の操作に対して実行します.ここでvar s=0を注釈したら、一番外のvar s=10というsを見つけます.この時の作用域は大域作用域になります.得られた結果は11,12,13です.結論の3:変数を探す時、いつも一番近い関数が生成する時の作用域から探し始めて、もし見つけられなかったら上に探して、トップレベル(object->undefined) まで探します. b()メソッドの探索sの道function Bは典型的なクローズドされた書き方であり、関数パラメータの戻り方によって変数が文を実行した後もアクセスできます.上の本から出力されたデータが表示されているように.しかし問題があります. では問題が来ました.なぜadd方法ができて、クローズドによって毎回変わるのが最初の値ですか?本当に最初の出発点に戻ったとしか言えないですね.言っても心が詰まる.JavaScriptの高級なプログラムの設計の中で、それはとても良い大きい本の赤色の本で、人民教育出版社の第3版の第70ページ、パラメーターの章節を伝える中でこのような1段の話を書いていて、結論の4:「ECMAScriptのすべての関数のパラメータは値によって伝達されます.基本型の値の伝達は基本型変数のコピーのように、参照型変数の伝達は参照型データ型変数のコピーのようになります.」と分かりやすく説明しました.()の時はこのような結果です.sは基本的なNumberタイプです.sを使わなければならないなら、どうすればいいですか? は、基本タイプの値転送を参照タイプの値転送 に変更する.
クローズド:関数生成時に近くの「値」を捕獲できる関数です.
転載または引用の場合は、出典を宣言してください.
解決する問題は、メソッドAからメソッドBに定義された変数を使用することです.
クローズド:関数生成時に近くの値を取り込むことができる関数です.
function B() {
var s = 0;
return function() {
return A(s);
}
};
function A(s) {
s++;
console.log(s);
}
var b = B();
b();
: 1
[Finished in 0.2s]
満足しています.sの値は関数生成時に近くの「値」を捕獲したからです.ちょっと不満ですが、問題を説明できます.sが使われました.そして...
var b = B();
b();
b();// 3 b();
b();
b();
....
1
1
1
1
[Finished in 0.2s]
これはおかしいですね.なぜですか?なぜいつも1ですか?毎回1を入れるべきですか?私も分かりませんvar s = 10;
function B() {
var s = 0;
add = function() {
s++;
console.log(s);
}
....
};
function A(s) {
....
}
var b = B();
b();
b();
add();
add();
add();
1
1
1
1
1
2
3
[Finished in 0.2s]
これはもっとおかしいです.b()方法は毎回1しかないというなら、add方法も1に戻るしかないはずです.もう一つの問題は、add方法が全体的な方法であることに気づきました.もし呼び出したら、変数によってコール先から検索したら、sの値は10であるべきです.結論の1:これにより、add関数が生成されると、関数が生成された時のsの値(var s=0)をキャプチャしたクローズドが生成されることがわかる....
var b = B();//
...
b();
b();
したがって、ここでは関数Bのために生成されたところで、add方法はBの中にもあるので、add生成の場所であり、また、add方法は大域的な方法であり、var b=B()がない場合には、関数も実行されるはずです.コードの先頭にはvar s=10がありますので、じゃ、そうですか?コードは以下の通りですvar s = 10;
function B() {
var s = 0;
add = function() {
s++;
console.log(s);
}
return function() {
return A(s);
}
};
function A(s) {
s++;
console.log(s);
}
// var b = B();
// b();
add();
add();
add();
実行結果は以下の通りです.add();
^
ReferenceError: add is not defined
結果はadd法のnot definedである.結論の2:add方法は大域的な方法であるが、それはB()の中に存在し、B()だけが実行され、add方法が定義されているものに相当する.さもなければ定義されていない.付:最初に自分の考えはB()の方法が定義されていないので、文脈は存在しません.当てずっぽうで,ご指摘を歓迎します.var b = B();
b();
b();
b();
add();
add();
add();
1
1
1
1
2
3
[Finished in 0.2s]
また最初の出発点に戻って、ぼんやりとJsの前に立っています.どうすればいいですかこの二つが使うsは同じものではないですか?やっぱりvar s = 10;
function B() {
// "use strict";s
var s = 0;
var c = {
value: 0
};
add = function() {
s++;
console.log('add...' + s)
}
return function() {
return A(c);
}
};
function A(c) {
c.value++;
console.log('A...' + c.value);
}
var b = B();
b();
add();
add();
b();
add();
b();
b();
A...1
add...1
add...2
A...2
add...3
A...3
A...4
[Finished in 0.4s]
締め括りをつけるクローズド:関数生成時に近くの「値」を捕獲できる関数です.