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

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

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

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

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

Q&A

解決済

2回答

281閲覧

JavaScriptのクロージャについて

terachapple

総合スコア12

JavaScript

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

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

0グッド

1クリップ

投稿2019/05/25 06:10

前提・実現したいこと

初めて質問させていただきます。

現在、JavaScriptを勉強しており、クロージャの概念について学んでいるのですが、わからない部分があります。

まず、以下のコードに対する私自身のクロージャの理解について・・・

JavaScript

1 function makeCounter1() { 2 var count = 0; 3 return f; 4 function f() { 5 return count = count + 1; 6 } 7 } 8 var counter1 = makeCounter1(); 9 console.log(counter1()); //-> 1 10 console.log(counter1()); //-> 2 11 console.log(counter1()); //-> 3

makeCounter1関数の中でさらにf関数を作り、その中でmakeCounter1関数のローカル変数であるcount変数を参照することでガベージコレクションの適応を免れmakeCounter1関数のオブジェクトの値を保持することができる。ということがこの場合のクロージャの機能だと理解しています。

ここまではいいのですが、自分が悩んでいる部分はこのコードを少しいじった次のコードでの問題です。
自分の予測では次のコードでも同じ結果が表示されると考えていました。

JavaScript

1 function makeCounter2() { 2 var count = 0; 3 count = count + 1; //先ほどf関数の中にあったこの部分のコードを外に出した 4 return f; 5 function f() { 6   return count = count; //count変数を参照するためだけのコード 7 } 8 } 9 var counter2 = makeCounter2(); 10 console.log(counter2()); //-> 1 11 console.log(counter2()); //-> 1 12 console.log(counter2()); //-> 1

(count変数に何の変更も加えておらず、何の生産性もないコードではあるが)f関数の中で一応count変数を参照しているためガベージコレクションの適応を受けずに値が保持された状態になり、makeCounter2関数を呼び出すたびにcount変数が1ずつ足されていくのだと思っていたのですが結果はそうではありませんでした。

問題は明らかに count = count + 1; の部分をf間数の外に出してしまったことにあると思うのですが自分の理解ではなぜこの部分がいけないのか発見することができませんでした。

なにかわかる方がいらっしゃいましたらご回答お願いいたします。

これが最初の質問となるので、質問の仕方に不適切・不明瞭な点があるかと思いますがもしよろしければ、その点についても忌憚のないご意見お願いいたします。

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

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

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

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

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

guest

回答2

0

クロージャーを使った場合の変数がどうなっているのか分かりやすいコードを書いてみました。
スコープを限定出来るというのが分かるでしょうか?

natuhaatsuine

1(function(){ 2 var a=12; 3 (function(){ 4 var b=222; 5 console.log('incl-b:'+b); 6 })(); 7 console.log(typeof a); 8 console.log(a); 9 console.log(typeof b); 10 console.log(b); 11})();

投稿2019/05/25 07:18

hentaiman

総合スコア6421

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

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

terachapple

2019/05/25 08:30

迅速なご回答ありがとうございます。 スコープの限定の概念についても今一度学ぶ必要性を感じました。 自分でもいろいろ調べたところ、 ```JavaScript var counter2 = makeCounter2(); ``` の部分の処理を、 ```JavaScript var counter2 = makeCounter2; ``` で行う処理と勘違いしたことによるものでした。 ```JavaScript var counter2 = makeCounter2(); ``` の場合、counter2()を実行すると ```JavaScript function f() { return count = count; //count変数を参照するためだけのコード } ``` この部分の処理しか行われていないため、当然count変数の数値が変動することはなく、結果の表示で1が続いていたのだと思われます。
hentaiman

2019/05/25 08:45

それはそうなんですが、クロージャーについてって部分はそれでもう解決したんですか?解決したなら何よりですが
terachapple

2019/05/25 10:28

何度もコメントいただいてすいません。 自分の知識が浅いせいで、ただの文法に対する思い違いを、新しく学び始めたクロージャについての不理解だと決めつけていました。 その結果タイトルに「クロージャについて」と銘打ってしまったのですが、本当の問題は文法に対する思い違いだったことに気がつきました。 手を煩わせてしまって申し訳ないです。ご回答ありがとうございました。
guest

0

ベストアンサー

count = count + 1の記述位置が変わることで
var count = 0;により毎回countが0になるため
count = count + 1 の結果が毎回1になっています。

counter1() のほうは function f() だけ実行されて
var count = 0; の影響を受けないのでcountが0に戻ることがないのです。

投稿2019/05/25 06:30

編集2019/05/25 06:35
yasutomi

総合スコア2937

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

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

terachapple

2019/05/25 08:30

迅速なご回答ありがとうございます。 自分でもいろいろ調べたところ、 ```JavaScript var counter2 = makeCounter2(); ``` の部分の処理を、 ```JavaScript var counter2 = makeCounter2; ``` で行う処理と勘違いしたことによるものでした。 ```JavaScript var counter2 = makeCounter2(); ``` の場合、counter2()を実行すると ```JavaScript function f() { return count = count; //count変数を参照するためだけのコード } ``` この部分の処理しか行われていないため、当然count変数の数値が変動することはなく、結果の表示で1が続いていたのだと思われます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問