9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

クロージャとスコープ

Last updated at Posted at 2016-08-05

クロージャ

一般的なクロージャのサンプル

function closure(val) {
  let count = val;
  
  const innerFunc = function(){
    return ++count;
  }
  return innerFunc;
}

const myClosure = closure(100);
console.log(myClosure()); //101
console.log(myClosure()); //102
console.log(myClosure()); //103

・普通の関数は一度実行されると領域を解放するが
・ここではinnerFuncそのものがmyClosureに格納されている状態
・スコープチェーンが破棄されないので
・innerFuncのCallオブジェクトのローカル変数countは、myClosureが有効な限り破棄されない

使用例

カウンター
http://codepen.io/mo4_9/pen/OXNjgp
カウンターのDOMを100個生成してるが、カウンター1個のときとコードは1行も変わらない。

クロージャとカスタムイベントを使った応用編
http://codepen.io/mo4_9/pen/RREGwO

スコープ

スコープチェーンの理解。マスキングしないと親関数に同名の変数を探しにいってしまう。

デモ:http://codepen.io/mo4_9/pen/yJObBw

var btn = document.querySelectorAll('.btn');

for(var i = 0; i < 10; i++) {
  // パラメータにiを指定 この関数スコープにローカル変数iが定義される(マスキング)
  (function(i, text){ // 即時関数がないとiはすべて、親関数のiを参照し9になる
    btn[i].addEventListener('click', function(){
      alert(text + i);
    }, false);
  })(i, 'ローカル変数i= ');
}

とはいえ、ES6で書けばブロックスコープが有効なので
以下のようにシンプルに書ける。

const btn = document.querySelectorAll('.btn');

for(let i = 0; i < 10; i++) {
    btn[i].addEventListener('click', () => {
      alert('ローカル変数i= ' + i);
    }, false);
}

参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?