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

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

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

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

Q&A

解決済

1回答

374閲覧

javascriptでクロージャがセットされている変数名を表示させたい場合

moriman

総合スコア615

JavaScript

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

0グッド

1クリップ

投稿2019/11/02 01:07

javascript

1function createCounter() { 2 let count = 0; 3 // `increment`関数は`count`変数を参照 4 function increment() { 5 count = count + 1; 6 return count; 7 } 8 return increment; 9} 10// `myCounter`は`createCounter`が返した関数を参照 11const myCounter = createCounter(); 12console.log(myCounter()); // => 1 13console.log(myCounter()); // => 2 14// 新しく`newCounter`を定義する 15const newCounter = createCounter(); 16console.log(newCounter()); // => 1 17console.log(newCounter()); // => 2 18// `myCounter`と`newCounter`は別々の状態持っている

よくあるjavascriptのクロージャのサンプルを見ていてふと頭に浮かんだことで、調べ方がわからないので質問させていただきます。
上記サンプル実行で
1
2
1
2
と表示されるんですが、これをグローバルスコープで実行した変数名も表示したい場合、つまり上記サンプルだと、
myCounter--1
myCounter--2
newCounter--1
newCounter--2
のように表示したい場合、どんなコードを書いたらよいでしょうか。

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

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

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

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

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

Lhankor_Mhy

2019/11/02 01:46 編集

補足願います。 たとえば、myCounterを別の変数に代入した場合、 const myCounter = createCounter(); const myCounterReferance = myCounter; console.log(myCounter()); // => myCounter--1 console.log(myCounterReferance()); // => myCounterReference--2 console.log(myCounterReferance()); // => myCounterReference--3 console.log(myCounter()); // => myCounter--4 こうなることを期待していますか?
moriman

2019/11/02 02:08

追記・修正依頼をいただきましてありがとうございます。 質問投稿時は提示頂いたような、また別の変数に代入するコードは頭にありませんでしたが、 まあ学習としてやっているので、提示して頂いたケースについても考えてみたいと思います。
Lhankor_Mhy

2019/11/02 04:54

「実行した変数名」とは具体的には一体何を指すのか、ということをお聞きしたかったのですが、jun68yktさんのご回答で解決しそうなら、それでいいかと思います。
moriman

2019/11/02 05:31

質問文中の「実行した変数名」はmyCounterやnew Counterのことでした。と言ってもconstで宣言しているので定数ですね。失礼しました。
guest

回答1

0

ベストアンサー

こんにちは

以下のように、 createCounter に引数を追加して文字列を渡せばよいかと思います。

javascript

1function createCounter(name) { 2 let count = 0; 3 4 function increment() { 5 count = count + 1; 6 return `${name}--${count}`; 7 } 8 return increment; 9} 10 11const myCounter = createCounter('myCounter'); 12console.log(myCounter()); // => myCounter--1 13console.log(myCounter()); // => myCounter--2 14 15const newCounter = createCounter('newCounter'); 16console.log(newCounter()); // => newCounter--1 17console.log(newCounter()); // => newCounter--2 18

参考になれば幸いです。

投稿2019/11/02 01:41

jun68ykt

総合スコア9058

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

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

moriman

2019/11/02 02:04

こんにちは。回答をいただきましてありがとうございます。 期待通り動きました。 確認なんですが。ぱっと見、仮引数のnameが、createCounter実行終了時に消えてしまうような気がしたのですが、 count変数と同様、仮引数name変数もクロージャであるincrement関数内から参照されている。 ↓ そのincrement関数がグローバルスコープでmyCounter変数やnewCounter変数から参照されている。 なので、createCounter関数が実行終了してもname変数と、それに渡された「myCounter」「newCounter」文字列も消えずに保持されている。 なので、myCounterを複数回実行した場合「myCounter」という文字列もその都度表示される。 ということですよね。
jun68ykt

2019/11/02 02:17

はい。そのご理解で合っています。createCounter が increment を返して終了した後も、そのincrement からは name を参照できて、その name は、そのincrementが作成されたときに name に渡された値(への参照)を保持しています。後から呼ばれた、createCounter('newCounter'); によって、既存のクロージャー increment から参照する name がすべて同じ 'newCounter' という値に上書きされてしまう、ということにもなく、それぞれ個別の文字列への参照を、クロージャー increment からは同じ name という名前で持ちます。
moriman

2019/11/03 00:34

理解できました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問