javascript
1function fn(n) { 2 var cnt = n; 3 return function() { 4 return ++cnt; 5 } 6} 7var f = fn(0); 8f() // 1
このようにクロージャー
を使った変数の保持をしている場合、
f
の現在のcnt
という変数名と値を取得することはできますか?
(chromeのdevtoolを用いれば見れることは知っています。)
##追記
chromeを使った場合なのですが
・関数定義&1回使用
・windowオブジェクトみる
・さっき作った関数を確認
こんな感じでその関数に付随するスコープが確認でき、さらにその中身の値まで知ることが出来ます。
どこかに保持されているのならjavascript
を用いて(例えば実際は無いですがfunc.scopes
でスコープオブジェクトが出てきたりとかで)確認する方法がないかなーと思った次第です。
好奇心からの質問であり、特に用途は考えていないのでまったくもって意味のない事の可能性もあります、すみません・・・
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答7件
0
クロージャの仕組みは、レキシカル環境(lexical environment)が関わってきます。
そして、レキシカル環境というのは、JavaScriptエンジンの内部処理を規定するための概念・用語であり、実際のコード(JavaScript)でアクセスする事は出来ません。
レキシカル環境は、....の定義に使用される仕様用のタイプです。
A Lexical Environment is a specification type used to define ...
...
レキシカル環境と環境記録の値は、純粋に仕様の仕組みであり、ECMAScript実装の特定の現実物に対応する必要はありません。 ECMAScriptプログラムがそのような値(レキシカル環境・環境記録)に直接アクセスしたり操作したりすることは不可能です。
......
Lexical Environments and Environment Record values are purely specification mechanisms and need not correspond to any specific artefact of an ECMAScript implementation. It is impossible for an ECMAScript program to directly access or manipulate such values.
...
クロージャとレキシカル環境の関係
レキシカル環境(lexical environment)
レキシカル環境とは、大まかにいうと、コード実行処理時に形成される領域と、それに伴う変数の記録簿の事です。また、両方を指す場合にも使われます。
コードが処理され始め、グローバルが処理されている時や関数が呼び出された際に、レキシカル環境は生成されます。今JSエンジンが処理している部分を含む"領域"をレキシカル環境といい、その外側を外側レキシカル環境といいます。
例えば、以下のコードを見て下さい。
js
1// グローバル 2 3←(JSエンジン処理点) 4 5var goku = "Son Goku"; 6
レキシカル環境: グローバル
外側レキシカル環境: null
です。
レキシカル環境にはgoku
という識別子が記録されており、値"Son Goku"
が対になって保存されています。
グローバルの外側はないので、その様な場合、外側レキシカル環境はnull
になります。
また、先程述べたように、関数が呼び出された際にも、レキシカル環境は生成されます。
js
1// グローバル 2 3 4var goku = "Son Goku"; 5 6function greeting(){ 7 // ローカル(ローカル) 8 ←(処理点) 9 10 console.log( "hi" ) 11} 12 13 14greeting(); ←(処理点: 定義内処理中)
レキシカル環境: greeting関数内
外側レキシカル環境: グローバル
処理がグローバル → 関数 へ移ると、関数内の新たなレキシカル環境が生成され、グローバルを処理していた時に作成されたレキシカル環境は消滅します。
クロージャ(closure: 閉包)
クロージャとは、関数が入れ子状で定義されており、且つ、コード実行時に内側の関数が返却された場合、その返却された関数の外側レキシカル環境が維持される、というメカニズムです。
抽象的すぎて分かりにくいので、実際にコードを元に見ていきましょう。
js
1function outer() { 2 // `inner`の外側 レキシカル環境 3 4 var cnt = 0; 5 function inner() { 6 // `inner`のレキシカル環境 7 8 return ++cnt; 9 } 10 return inner; 11}
関数inner
のレキシカル環境には、変数は宣言されていません。関数inner
の外側レキシカル環境には、変数cnt
が宣言されています。
先程も言いましたが、関数が実行される際にこのレキシカル環境は生成され、変数もそこに保存されます。そして、関数の処理が終われば、この両方のレキシカル環境も消去されてしまいます。
ところがです。関数を返却する関数の場合は(関数outer
)、その返却された関数(関数inner
)の外側レキシカル環境は維持されたまま、関数にくっ付いた状態で返却されるのです。
ですので、返却される予定の関数inner
内で、その外側レキシカル環境の変数ctn
にアクセスするような処理を書いておくことにより、返却後、inner関数を実行することによって、維持された状態の外側レキシカル環境(変数)にアクセスする事ができるのです。
もちろん、変数ctn
は関数内で定義されているので、その外側からはアクセスできません。
js
1function outer() { 2 var cnt = 1; 3 4 function inner() { 5 return ++cnt; 6 } 7 return inner; 8}
これがクロージャの仕組みです。
メソッドによるクロージャ
今後、余裕があれば追記致します(。•ㅅ•。)
追記
高評価を頂けた方・冷静に適切なコメントを頂けた方、ありがとうございます。一部の荒らし者がコメントに混入してきた為、追記は削除しました(。•ㅅ•。)???? 通知でご迷惑をお掛けしていたら、すみません(。•ㅅ•。)????
投稿2019/06/20 12:55
編集2019/06/21 17:13
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/20 23:21
2019/06/21 01:15 編集
2019/06/21 03:14 編集
2019/06/21 03:27
2019/06/21 03:30

退会済みユーザー
2019/06/21 04:08

退会済みユーザー
2019/06/21 04:10

退会済みユーザー
2019/06/21 05:45 編集
2019/06/21 04:18
2019/06/21 04:19
2019/06/21 04:21
2019/06/21 04:24
2019/06/21 04:26 編集
2019/06/21 04:38 編集
2019/06/21 04:32
2019/06/21 04:43 編集
2019/06/21 04:47
2019/06/21 04:59
2019/06/21 05:06
2019/06/21 05:09
2019/06/21 05:16
2019/06/21 05:26
2019/06/21 05:27
2019/06/21 05:35
2019/06/21 05:40
2019/06/21 05:42
2019/06/21 05:45
2019/06/21 05:46
2019/06/21 05:47
2019/06/21 05:47
2019/06/21 05:47
2019/06/21 05:50
2019/06/21 05:51
2019/06/21 05:55
2019/06/21 06:02
2019/06/21 06:05
2019/06/21 06:05
2019/06/21 06:07

退会済みユーザー
2019/06/21 06:08 編集
2019/06/21 06:08 編集
2019/06/21 06:09
2019/06/21 06:09
2019/06/21 06:09
2019/06/21 06:11
2019/06/21 06:11
2019/06/21 06:12
2019/06/21 06:13
2019/06/21 06:13

退会済みユーザー
2019/06/21 06:19
2019/06/21 06:19
2019/06/21 06:20
2019/06/21 06:20
2019/06/21 06:24
2019/06/21 06:25
2019/06/21 06:28 編集
2019/06/21 06:38 編集
2019/06/21 11:59 編集
2019/06/21 12:01

退会済みユーザー
2019/06/21 13:01 編集
2019/06/21 12:42
2019/06/21 12:50
2019/06/21 13:31

退会済みユーザー
2019/06/21 14:56 編集
2019/06/21 15:30
2019/06/21 15:31
2019/06/21 16:14
2019/06/21 16:39 編集

退会済みユーザー
2019/06/21 17:55
2019/06/21 21:16

0
ベストアンサー
Object.keys(obj)を用いてオブジェクトのプロパティを得る事ができるように
関数オブジェクトに紐づいているクロージャースコープの変数の値をとる手法ってないのかな?
標準的なJavaScriptには用意されていません。
投稿2019/06/20 07:27
総合スコア146387
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
スコープ外の変数を取得することは出来ません。
(取得する裏技があったら、スコープの意味がありません)
JavaScript
1function fn(n) { 2 var cnt = n; 3 return function() { 4 return ++cnt; 5 } 6}
変数 cnt
は「関数 fn 内」及び「関数 fn の内部関数」のみにスコープがあります。
Re: domidomi さん
投稿2019/06/20 11:51
編集2019/06/20 11:58総合スコア18194
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
変化球っぽいですがオブジェクトとして返してあげれば良いのでは?
js
1function fn(n) { 2 var cnt = n; 3 return function () { 4 ++cnt; 5 return {cnt} 6 } 7} 8var f = fn(0); 9console.log(f()); // { cnt: 1 } 10console.log(f()); //{ cnt: 2 } 11console.log(Object.keys(f())); //[ 'cnt' ]
投稿2019/06/20 11:04
総合スコア2826
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
クラス化する、インスタンス化する等はあります。
ただ、どうしてもクロージャで行いたいという要望の場合、隠ぺいが目的かと思いますので、取得とカウントする処理の関数各々かえせばいいんじゃないでしょうか。
javascript
1function fn(n) { 2 var cnt = n; 3 return { 4 up:function(){return ++cnt;}, 5 state:function(){ return cnt;} 6 } 7} 8var f = fn(0); 9f.up() // 1 10f.state() // 1
投稿2019/06/20 07:07
総合スコア1013
0
varで定義したものを取得する方法は知らないけど、thisならfnオブジェクトに属するものって事で取れます。
1 function fn(n) { 2 var cnt = n; 3 this.cnt2= n; 4 return function() { 5 //return ++cnt; 6 return this; 7 } 8 } 9 var f = fn(0); 10 f() // 1 11 console.log(f());
投稿2019/06/20 07:02
総合スコア6426
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/20 07:19
2019/06/20 07:42
2019/06/20 07:56

退会済みユーザー
2019/06/20 17:10 編集

退会済みユーザー
2019/06/20 17:23

退会済みユーザー
2019/06/21 04:29
2019/06/21 06:59
2019/06/21 07:11
2019/06/21 07:11

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。