アプリ版:「スタンプのみでお礼する」機能のリリースについて

javascriptのクロージャの例として下記のような例があります

function outer(){
var x = 1;

return function (){
console.log(x);
x = x + 1;
};
}

hoge=outer();
hoge(); //1
hoge(); //2
hoge(); //3


変数hogeに関数outerを代入し、hoge()を1回目に実行したときに「1」が返ってくるのは理解できます。

しかし、2回目以降にhoge()を実行したときに、カウントアップしたxが返ってくるのがわかりません
2回目以降の呼び出しの際にouter関数内のvar x = 1は実行されないのでしょうか?

A 回答 (3件)

-- hoge=outer();


関数 outer が実行される
outer の関数スコープに変数 x を用意 ... 1
変数 x を閉包(closure)する関数 inner(仮称) を作成
関数 outer が実行終了
outer の関数スコープは破棄されるが、
変数 x だけは関数 inner に閉包されたので存続

-- hoge(); //1
関数 inner が実行される
関数 inner に閉包された変数 x を出力 ... 1
関数 inner に閉包された変数 x を加算 ... 2
関数 inner が実行終了
閉包された変数 x は関数 inner が存在するため存続

-- hoge(); //2
関数 inner が実行される
関数 inner に閉包された変数 x を出力 ... 2
関数 inner に閉包された変数 x を加算 ... 3
関数 inner が実行終了
閉包された変数 x は関数 inner が存在するため存続
    • good
    • 0
この回答へのお礼

詳細にありがとうございます!
理解できました!

お礼日時:2021/11/16 08:25

hogeにはouterが生成した関数が代入されます。


以後、hogeの呼び出しは生成された関数を実行するだけ。
outerは実行されません。
outerの呼び出しは一回だけです。
    • good
    • 0
この回答へのお礼

なるほと、outerそのものが入ってるのかと思いましたが、returnされたinner関数が入っているのですね!

お礼日時:2021/11/16 08:26

こんばんは



>2回目以降の呼び出しの際にouter関数内のvar x = 1は実行されないのでしょうか?
されません。

hoge の内容は、outerから返される無名関数です。
その内容には
 var x = 1;
は含まれていませんよね?

例えば、 console.log(hoge); としてみれば、
 ƒ (){
  console.log(x);
  x = x + 1;
 }
のような関数が返されることからも、確認できると思います。
hoge() を実行すれば、当然ながら上記の関数が呼ばれることになります。

変数 x は、定義された際にhogeのスコープにありますが、その後、hoge が実行される毎にインクリメントされてゆきます。
このような x が内包されるしくみを、クロージャと言うようです。

更に、別の変数として、
 fuga = outer();
 fuga();
 fuga();
などとすれば、outer が呼ばれた際に、fuga 内の変数 x は1に初期化されます。
(hoge内のxには影響しません)
    • good
    • 0
この回答へのお礼

ありがとうございます!
hogeにouterそのものが入っているのかと思いました

お礼日時:2021/11/16 08:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!