下記サイトの解説がとても分かりやすい
Question
次のような関数をつくるには?
(例:関数を実行するたびにカウントする)
f(); //-> 1 f(); //-> 2 f(); //-> 3
Answer
function outer() { function inner() { console.log('hello'); } } inner(); //-> error outer(); //-> not do anything
↓
function outer() { function inner() { console.log('hello'); } inner(); } outer(); //-> hello
↓
var inner = function() { console.log('hello'); }; inner(); //-> hello
↓
(function() { console.log('hello'); })(); //-> hello
↓
function outer() { var inner = function() { console.log('hello'); }; return inner; } var f = outer(); f(); //-> hello
↓
function outer() { return function() { console.log('hello'); }; } var f = outer(); f(); //-> hello
↓
function outer() { return function() { var x = 'hello'; console.log(x); }; } var f = outer(); f(); //-> hello
↓
function outer() { var x = 'hello'; return function() { console.log(x); }; } var f = outer(); f(); //-> hello
↓
function outer() { var x = 1; return function() { console.log(x); x++; }; } var f = outer(); f(); //-> 1 f(); //-> 2 f(); //-> 3
↓
var outer = function() { var x = 1; return function() { console.log(x); x++; }; }; var f = new outer(); f(); //-> 1 f(); //-> 2 f(); //-> 3 var f2 = new outer(); f2(); //-> 1 f2(); //-> 2 f2(); //-> 3
example
var hoge = function() { var isFlg = false; return function() { if (isFlg) { console.log('Is already running'); } else { console.log('run'); } isFlg = true; }; }; var f = hoge(); f(); //-> run f(); //-> Is already running f(); //-> Is already running
ハッカーと画家 付録:力
function foo(n) { return function(i) { return n += i; }; } var f = foo(1); console.log(f(1)); console.log(f(1)); console.log(f(2)); console.log(f(5));