クロージャーの利点はグローバル変数を使わずにコードがかけると認識しているのですが、
http://dqn.sakusakutto.jp/2009/01/javascript_4.h …
だとcがグローバルじゃないけどfがグローバル変数なんで結局グローバル変数が存在する事になって意味がないような気がします。
他のサンプルでもだいたいこんな形です。
それでもクロージャー使う方がいいのでしょうか?
ご教示頂けると幸いです。
No.6ベストアンサー
- 回答日時:
実際にクロージャを使わない実装をしてみると、わかりやすいと思います。
(1) クロージャを使わない例
https://ideone.com/QcpkE
(2) クロージャを使った例
https://ideone.com/DoWf2
(2) ではローカル変数 xがプライベート変数扱いとなり、外部からアクセスできなくなります。
var x; を他で宣言しても干渉しません。
一方、(1) では他のコードで var x; を宣言することで名前空間の衝突が発生します。
グローバル変数 x を宣言しない事は勿論、x に不正な値が代入されないように注意しなければなりません。
> クロージャーの利点はグローバル変数を使わずにコードがかけると認識しているのですが、
それも利点の一つですが、本質ではないと思います。
上のサンプルではどちらのコードでも匿名関数で括ればグローバル変数は宣言されません。ただし、変数 x のスコープは異なります。
グローバル変数を宣言したくないのなら、全コードを匿名関数で括ってやり、更に一段階深いクロージャにすればいいのです…。
コードまで示して頂きありがとうございました。
>> クロージャーの利点はグローバル変数を使わずにコードがかけると認識しているのですが、
>それも利点の一つですが、本質ではないと思います。
これで、何かスッキリしたというかふっきれた気持ちになりました。
No.5
- 回答日時:
// (1)
function combine (f, g) {
return function () {
return g(f());
};
}
function A() { alert('A'); }
function B() { alert('B'); }
function C() { alert('C'); }
var p = combine(A, B);
p(); // 'A', 'B'
var q = combine(B, C);
q(); // 'B', 'C'
関数と関数を組み合わせ、新しい関数を作り出しています。もし、これに条件を付けて「~のときは A と B」「~のときは B と C」のように関数を生成できたら、ひょっとすると「目的の動作をする関数を、自動的に作る関数」ができ上がるのではないでしょうか。
// (2)
function A (x, y, z) {
return x + y + z;
}
var p = A(1, 2, 3); // 6
言うまでもなく、x と y と z を足す関数です。しかし、「今は x と y のセットだけできるが、z が何か分からない」という場合もあるかもしれません。
function B (x, y) {
return function (z) {
return A(x, y, z);
};
}
var q = B(1, 2);
q(3); // 6
こうすれば、先に x と y だけセットしておき、好きなタイミングで z をセットして結果を得られます。
---
高階関数、部分適用、遅延評価あたりをキーワードにクロージャ(関数閉包)の使い道を考えてみて下さい。やろうと思えば制御文の多くがコードから消えます。
しかし、現状の JS エンジンではかなり遅くなるでしょう。また、No.4 で指摘されているように、メモリ管理に関する不安材料も若干あります。ですから多用は勧めません。やり過ぎると解せないスパゲッティになるのは、グローバル変数と大差ないです。
とは言え、一度はクロージャの使い道を模索して下さい。その後、元の書き方に戻るにしても、コードの見え方が違うと思います。
No.4
- 回答日時:
私もよくわかっていないので、かならずしも正しくはないと思いますが…
>クロージャーの利点はグローバル変数を使わずにコードがかけると
>認識しているのですが
変数化しなくてすむというのは匿名関数を利用することによるもなので、説明用のサンプルがとても簡単なものにしているためにそう見えるだけではないでしょうか?
クロージャ的にすると、その環境も保持されるというのが一番大きなメリットではないでしょうか?
変数の引渡しや管理をしなくても済むので便利という面もあります。
簡単な例はNo1様が提示なさっているので、応用例にしてみると・・・
以下のように、アニメーションで複数の要素を同時に扱おうとするときに便利とか…
(例では処理関数を並行して実行させていますが、同じことをやるにしても、目的の機能を持つプロトタイプを作成しておいて、複数の実体化すると言う方法もあります)
>それでもクロージャー使う方がいいのでしょうか?
必要を感じなければ使わない方が良いみたい。
(クロージャを使うことが、メモリーリークの原因になりやすいようなので)
クロージャなしに書き直してみれば、利点がわかるかと思います。
(全角空白は半角に)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head><title>sample</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<style type="text/css">
div div { width:100px; float:left; margin:10px; overflow:hidden; }
</style>
<script type="text/javascript">
<!--
function test(evt){
var t = evt.target || evt.srcElement;
if (t.nodeName != "DIV" || t.className.match(/\bactive\b/)) return;
var hh = t.clientHeight;
t.className += " active";
slide(t, hh, 0, function(){
slide(t, 0, hh, function(){
t.className = t.className.replace(/ active$/, "");
});
});
}
function slide(node, start, end, callback){
var s = node.style, f = start<end;
var h = start, step = f?2:-6;;
var intervalId = setInterval(function(){
h += step;
if ((f && end<h) || (!f && end>h)) h = end;
s.height = h + "px";
if (h==end) {
clearInterval(intervalId);
node = s = null;
if (callback) callback();
}
}, 30);
}
//-->
</script>
</head>
<body>
<div onclick="test(event)" style="width:400px;">
<div style="height:150px; background-color:red;"></div>
<div style="height:200px; background-color:blue;"></div>
<div style="height:250px; background-color:green;"></div>
</div>
</body>
</html>
No.1
- 回答日時:
もんだい、その1
あるかんすうが、よばれるたびに、かうんとし、そのあたいをかえす、かんすうをかきなさい。
ただし、ぐろーばるへんすうは、つかわないものとする。
かうんとのしょきちは、さいしょにじゆうなすうちからはじめられるものとする。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonのグローバル変数 2 2022/11/25 18:02
- C言語・C++・C# 競技プログラミングに関する質問です。 3 2022/04/03 19:51
- FTTH・光回線 グローバルIPアドレスの変更について 1 2022/04/23 05:32
- 格安スマホ・SIMフリースマホ Xiaomi 12Tでau回線のVOLTEが解放できません 7 2022/10/28 17:42
- VPN 接続のたびにIPが変わるVPNサービスが知りたい 2 2022/06/27 02:34
- 戦争・テロ・デモ ロシアは世界に向けて強いメッセージを送るべきではないでしょうか? 6 2022/06/25 00:42
- FTTH・光回線 Softbank光でDDNS設定 1 2022/07/30 07:20
- その他(インターネット接続・インフラ) IPアドレスについて 2 2022/10/23 14:48
- 社会学 グローバル化がわたしたちの暮らしや社会にもたらした利点と問題点とは何ですか? 4 2023/04/23 02:37
- 経済 コストコの時給はなぜ高い? 7 2023/07/18 12:23
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数でy=g(x)のgとは何の略です...
-
idを使わずにonclickで自身の要...
-
[Delphi]入れ子(?)になったプロ...
-
jQueryを使用して以下のような...
-
functionから別のfunctionを実...
-
ActiveXobjectが作成できない
-
JavaScriptで決まった「時刻」...
-
C#テキストボックスの文字を配...
-
Boolean型配列中のTrueの有無を...
-
google apps scriptの終了のさせ方
-
jspからjavascriptの変数引継ぎ
-
任意の座標をクリックさせるには
-
Linux バイナリ実行できない "...
-
javascriptでスロットゲームを...
-
window.openでタイトル名の指定
-
javascriptでiframeのURL変更は?
-
javascript 特定のタグのidの存...
-
翌月を取得するGASが分かりません
-
ASP.NETのコントロールの値をJa...
-
VSCODE[Python]の設定について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
functionから別のfunctionを実...
-
idを使わずにonclickで自身の要...
-
関数でy=g(x)のgとは何の略です...
-
jslintのエラーについて質問
-
jQueryの :not() .not() が有効...
-
クリックすると上に開くアコー...
-
jQueryのプラグイン「Skitter」...
-
関数名をテキストから読み込む...
-
小数点以下を5刻みで表示
-
XMLHttpRequestでキャッシュを...
-
jQueryでzipを解凍読み込みする...
-
Matlabで自作関数をオーバーロード
-
javascript(jQuery)でセル内...
-
要素名がスペースを含む場合のj...
-
ページ内に複数表がある場合のT...
-
処理前の「お待ちください」
-
JS 頭文字が大文字について
-
HTML5でファイルドラッグ&ドロ...
-
Javascriptリアルタイムエラー...
-
getElementByIdを使用したグロ...
おすすめ情報