Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ちょっと詳しくJavaScript 第4回【スコープとクロージャ】

2,610 views

Published on

Published in: Technology
  • Be the first to comment

ちょっと詳しくJavaScript 第4回【スコープとクロージャ】

  1. 1. ちょっと詳しくJavaScript 第4回【スコープとクロージャ】2011年07月22日 株式会社ランチェスター TEL: 03-5775-3395 Fax:03-5775-3396 URL: http://www.lanches.co.jp/
  2. 2. JavaScriptの変数とデータ型 数値型(number) 参照型(参照渡し) 文字列型(string)基本型 真偽型(boolean) var a = {val:1}; 特殊(null、undefined) var b = a; オブジェクト(object) b.val = 5;参照型 関数(function) alert(a.val); // 5 配列(object)基本型(値渡し) var a = [1, 2, 3]; var b = a;var a = 5; b[0] = 5;var b = a; alert(a[0]); // 5b = 10;alert(a); // 5 ※ 関数の参照渡しは実例を見せる のが難しいのでパス (´・ω・`) Proprietary and Confidential to Lanchester Co.,LTD. Page 1
  3. 3. JavaScriptの変数スコープ• グローバルスコープ • プログラム中のどこからでも参照可能• ローカルスコープ • その変数が宣言された関数の中でのみ参照可能この2つしかないです。 Proprietary and Confidential to Lanchester Co.,LTD. Page 2
  4. 4. JavaScriptの変数スコープ - 実例1var n = 1; // グローバルfunction f() { // ←実はこれもグローバル var n = 0; // ローカル return n;}alert(n); // 1alert(f()); // 0alert(n); // 1 Proprietary and Confidential to Lanchester Co.,LTD. Page 3
  5. 5. JavaScriptの変数スコープ - 実例2n = 1; // グローバルfunction f() { // ←実はこれもグローバル n = 0; // グローバル return n;}alert(n); // 1alert(f()); // 0alert(n); // 0関数内で「var」を付けた変数がローカルスコープとなる。グローバル変数の宣言は「var」を付けても付けなくても変わらない。 Proprietary and Confidential to Lanchester Co.,LTD. Page 4
  6. 6. ローカルスコープは関数全体で有効function f() { for(var i=0; i<10; i++) { // 特に何もしないよ } alert(i); // ※}f();※で「10」が表示される。JavaScriptに「ブロックスコープ」は存在しない。 Proprietary and Confidential to Lanchester Co.,LTD. Page 5
  7. 7. 関数名も変数なのでfunction f() { g(); // FunctionDeclarationにより function g() { // 先に実行式があっても問題ない alert("localFunc"); }}f(); // localFunc と表示g(); // スコープ外なので実行不可今までの考え方をそのまま活用でき、その通りの結果となる。 Proprietary and Confidential to Lanchester Co.,LTD. Page 6
  8. 8. 実は違った関数リテラルとFunction型var n = 1;function f() { var n = 0; var s1 = new Function("", "alert(n);"); var s2 = function() { alert(n); }; s1(); // 1→グローバルを参照 s2(); // 0→ローカルを参照}f();ECMAScriptの仕様により、Functionコンストラクタで作られる関数はグローバルオブジェクトのスコープを参照して実行される。 Proprietary and Confidential to Lanchester Co.,LTD. Page 7
  9. 9. 実は違った関数リテラルとFunction型 - 2// var n = 1;function f() { var n = 0; var s = new Function("", "alert(n);"); // エラー}f();グローバル変数nがないためそもそも定義しようとした時点でエラーとなってしまう。 Proprietary and Confidential to Lanchester Co.,LTD. Page 8
  10. 10. 仮引数もローカルスコープvar n = 1;function f(n) { n++; return n;}alert(f(10)); // 11alert(n); // 1同じ変数名だけど値渡しなのでグローバルのnはそのまんま。 Proprietary and Confidential to Lanchester Co.,LTD. Page 9
  11. 11. 仮引数もローカルスコープだけど・・・参照型var a = [1, 2, 3];function f(v) { v[0] = 10; return v;}alert(f(a)); // 10, 2, 3alert(a); // 10, 2, 3違う変数名だけど参照渡しなので実体が変更される。 Proprietary and Confidential to Lanchester Co.,LTD. Page 10
  12. 12. スコープチェインvar a = 1;function f() { var b = 2; function g() { var c = 3; return a + b + c; } return g();}alert(f()); // 6自分自身のスコープにない変数の場合スコープを順に辿っていき、変数を探し出す。 Proprietary and Confidential to Lanchester Co.,LTD. Page 11
  13. 13. ところでthisって<input type="button" value="test" id="btn"><script type="text/javascript">function where() { alert(this);}var o = { method: where };document.getElementById("btn").onclick = where;where(); // [object Window]o.method(); // [object Object]// [test]ボタンクリック // [object HTMLInputElement]</script>「誰の関数として実行されたか」がthisに入ってくる。特にイベントハンドラの場合には注意。 Proprietary and Confidential to Lanchester Co.,LTD. Page 12
  14. 14. 本命:クロージャ(Closure、閉包)• 引数以外の変数を実行時の環境ではなく、自身が定義された環境( 静的スコープ)において解決することを特徴とする • Wikipediaより• ローカル変数を参照している関数内関数 • @ITより• 関数自身が定義された環境を、ローカル変数も含めて持ち運ぶことの できる仕組み(またはそうした関数自体) • ZDNet builderより・・・何言ってんだか分かんねっす(´・ω・`) Proprietary and Confidential to Lanchester Co.,LTD. Page 13
  15. 15. シンプルなクロージャfunction closure(init) { var c = init; var f = function() { c++; return c; }; return f;}var counter = closure(5);alert(counter()); // 6alert(counter()); // 7alert(counter()); // 8return fにより返された関数(counter)は、それが生成されたタイミングでローカルスコープだったcを閉じ込めて(Closure/閉包)いる。 Proprietary and Confidential to Lanchester Co.,LTD. Page 14
  16. 16. 1つのクロージャを複数で使ってみるfunction closure(init) { var c = init; return function(){ return ++c; }}var c1 = closure(5);var c2 = closure(10);alert(c1()); // 6alert(c1()); // 7alert(c2()); // 11alert(c2()); // 12alert(c1()); // 8alert(c2()); // 13それぞれがclosureを実行したタイミングでクロージャが作られている。 Proprietary and Confidential to Lanchester Co.,LTD. Page 15
  17. 17. 総決算<input type="button" id="btn" value="設定"><script type="text/javascript">document.getElementById("btn").onclick = buttonState(true);function buttonState(flag) { return function() { flag = !flag; this.value = flag ? "設定" : "解除"; };}</script> Proprietary and Confidential to Lanchester Co.,LTD. Page 16
  18. 18. 株式会社ランチェスターTEL: 03-5775-3395 Fax:03-5775-3396URL: http://www.lanches.co.jp/

×