質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

458閲覧

javascript 入門 クロージャについて

fj-kakeru

総合スコア29

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/04/13 17:18

javascript

1function outer(){ 2 var x = 1; 3 4 return function (){ 5 alert(x); 6 x = x + 1; 7 }; 8 9} 10 11var f = outer(); 12f(); // 1 13f(); // 2 14f(); // 3 15</script>

なぜ上記のような結果になるのかわかりません。

関数内関数で x + 1がxに代入されているので、最初のfは2ではないのでしょうか?

alert(x)以下の式はalert(x)には関係ないのでしょうか。

また、最初に定義されているx=1は、2回目のfでは関係ないのでしょうか。

よくわかっていないのでわかりづらい文章ですが、教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

まず、この結果が1,2,3と表示されるのは理解できると思います。

javascript

1var x = 1; 2for(var i = 0; i < 3; ++i){ 3 alert(x); 4 x = x + 1; 5}

次に、ループの中身を関数にします。

カウントアップの部分が戻り値になります。
通常の関数はxの値を保持することができませんので、毎回引数にいれて更新する必要があります。

javascript

1var f = function(x){ 2 alert(x); 3 return x + 1; 4}; 5 6var x = 1; 7for(var i = 0; i < 3; ++i){ 8 x = f(x); 9}

さらに、クロージャを使って関数の外部の変数を関数内から利用し、更新します。
変数は関数の外部にありますので、関数呼び出しによって初期値にもどることはありません。(と理解してください。)

javascript

1var x = 1; 2var f = function(){ 3 alert(x); 4 x = x + 1; 5}; 6 7for(var i = 0; i < 3; ++i){ 8 f(); 9}

最後に、変数xを隠すためにfunctionで括ります。

質問のコードとほぼ同じになります。

javascript

1function outer(){ 2 var x = 1; 3 var inner = function(){ 4 alert(x); 5 x = x + 1; 6 }; 7 return inner; 8}; 9var f = outer(); 10 11for(var i = 0; i < 3; ++i){ 12 f(); 13}

投稿2018/04/13 18:10

編集2018/04/13 18:15
iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

関数内関数で x + 1がxに代入されているので、最初のfは2ではないのでしょうか?

alert関数によるダイアログ表示が, x=x+1の実行に呼び出されている以上, 出力される内容は初期値である1です. また, alert関数はスクリプトの実行をブロックするため, この時点ではまだ関数fの処理は完了していません.

alert(x)以下の式はalert(x)には関係ないのでしょうか。

次回の関数f呼び出しに影響する処理が記述されているため"関係ない"とは言えません.

また、最初に定義されているx=1は、2回目のfでは関係ないのでしょうか。

outer関数呼び出し時に生成されたスコープを関数fが参照し続けているため, そのスコープで定義された変数xは残り続けます. ただしx=1という代入処理はouter関数呼び出しの際に一度だけ行われます.

NOTE:
alertx=x+1の行を入れ替えたコードを実行し, その動作の違いについて比べてみて下さい.

JavaScript

1function outer(){ 2 var x = 1; 3 4 return function (){ 5 x = x + 1; 6 alert(x); 7 }; 8 9} 10 11var f = outer(); 12f(); // ? 13f(); // ? 14f(); // ?

投稿2018/04/13 21:12

defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問