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

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

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

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

Q&A

4回答

1224閲覧

javascriptの出力について

tanakashouzoux

総合スコア52

JavaScript

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

0グッド

0クリップ

投稿2020/06/14 08:22

編集2020/06/15 01:04

以下のコードについて疑問が4つあります

詳しい方ご教示頂けないでしょうか???

尚以下のコード、コード内の日本語は本に書いてあったものをそのまま引用しています。

引用元「開眼!Javascript p101」

javascript

1>var countUpFromZero = function() { 2>var count = 0; 3>return function() { // 子関数を返す 4>return ++count; // 変数 count は親関数で定義されている 5>}; 6>}(); // countUpFromZero は呼ばれると即時実行し、無名関数を返す 7>/* countUpFromZero() に返された子関数はその親関数の変数 count にアクセスする必要がある 8>ため、それを保持する。countUpFromZero() を実行するたびに return ++count が実行される。 9>*/ 10>console.log(countUpFromZero()); // 出力:1 11>console.log(countUpFromZero()); // 出力:2 12>console.log(countUpFromZero()); // 出力:3

1.このコードではまず即時関数

引用テキストfunction() {var count = 0;

return function() { // 子関数を返す
return ++count; // 変数 count は親関数で定義されている
};
}();

が書かれていて、即時関数なので書いた瞬間に実行され、その結果
「countUpFromZero」
には

function() { // 子関数を返す
var count = 0;
return ++count; // 変数 count は親関数で定義されている
};」

が入っていると考えたのですが、これは間違っているのでしょうか?

2.「関数countUpFromZero」を1回だけ「countUpFromZero();」で呼び出した時、
「countUpFromZero」
には

function() { // 子関数を返す

var count = 0;
return ++count; // 変数 count は親関数で定義されている
};」

が入っているので、この無名関数が実行され、その結果
「countUpFromZero」
には
「count=1」
が入ると考えたのですがこれは間違っているのでしょうか?

3.2の考えがもし合っているのであれば上記コードのs「出力1、出力2、出力3」は間違っている気がするのですが、合っているのでしょうか?
実際に上記コードを私がコンソールで実行した所「undefined」と表示されてしまいました・・・

---以下追記した部分となります---

私が間違っていると思ったのは、私は出力1の所にcount=1,出力2の所にcount=2,出力3の所にcount=3,がコンソールに表示されると思ったので間違っていると考えました

あと、上記コードをGoogle developer toolsのconsoleの所に貼り付けてenterキーを押して確かめたところundefinedと表示されてしまいました・・・

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

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

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

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

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

kei344

2020/06/14 08:42

「間違っているのでしょうか」というのは、なぜそう思ったかを書きましょう。また、「私がコンソールで実行した所「undefined」と表示されてしまいました」と前の質問にも書かれていましたが、試し方とその確認方法に問題があるのでは。
tanakashouzoux

2020/06/14 10:51

kei344さん いつもご指導ありがとうございますm(__)m 仰る通りですね???? 私が間違っていると思ったのは、私は出力1の所にcount=1,出力2の所にcount=2,出力3の所にcount=3,がコンソールに表示されると思ったので間違っていると考えました あと、上記コードをGoogle developer toolsのconsoleの所に貼り付けてenterキーを押して確かめたところundefinedと表示されてしまいました・・・
kei344

2020/06/14 11:13

この「質問への追記・修正の依頼」の部分はデフォルトで表示されませんので、質問本文に追記することをお勧めします。 また、コンソールは最後の行しか見ていないのではないでしょうか。提示のコードをコンソールに入れてエンターを押すと、「1」「2」「3」「undefined」の4行が表示されます。最初の3つがコード実行中に関数内で呼ばれている「console.log」による出力で、最後の「undefined」は貼り付けたコードが何も返さないコードだからです。
tanakashouzoux

2020/06/14 11:21

kei344さん 何度もありがとうございますm(__)m 今もう一度新しくタブを立ち上げて貼り付けたところ最後の行に1,2,3,undefinedと出ました! ありがとうございますm(__)m 私は「1」「2」「3」の所が「count=1」「count=2」「count=3」とコンソールに表示されると思ったのですが、なぜ「1」「2」「3」と表示されるのでしょうか・・・
tanakashouzoux

2020/06/14 11:22

すいません 御指導頂いた様に質問の方に先程の記述を追記させて頂きたいと思いますm(__)m
kei344

2020/06/14 11:25

「count=」なんて文字列を渡していないから。
tanakashouzoux

2020/06/14 12:02

kei344さん 何度も何度もありがとうございますm(__)m 例えば return function(){}; であれば呼び出し元に function(){}; という関数を戻すと思うのですが return ++count; (⇔retun count=count+1) の場合は呼び出し元に count=count+1 を戻すのではないのでしょうか???
kei344

2020/06/14 12:22

関数は式を返しません。結果を返します。
think49

2020/06/14 12:26 編集

もう少し、その結果に至ると考えたロジック(過程)を詳細に書くことをお勧めします。 「なぜそう考えたのか?」の自問をループさせれば、もっと出てくると思います。
think49

2020/06/14 12:33 編集

それと、tanakashouzouxさんがそう考えるに至った資料となるURLを掲示することをお勧めします。 何もないところから、一から考えを作ったわけではないはずです。 考えの元となった資料、「この資料によれば~とあるので、~と考えた」のように書けます。 ただ、ここ最近の質問を見ていると、対応する資料を探して読んでいるのか、怪しく感じる印象はあります。
think49

2020/06/14 12:52

> 尚以下のコード、コード内の日本語は本に書いてあったものをそのまま引用しています。 ・主文と引用文が明確に区別できること ・引用元を掲示すること が引用の条件です。 「引用元(書籍名、ページ数)」の掲示し、引用文の行頭に "> " をつけて下さい。 teratailでは、コードブロックと引用符を併用できます。
tanakashouzoux

2020/06/14 21:48

think49さん わざわざ丁寧なご指導ありがとうございますm(__)m teratailの基本作法さえ知らない不躾な私にまで優しく指導して下さり本当にありがとうございますm(__)m 早速指導頂いた様に自問をループさせつつ、質問を編集させて頂きたいと思いますm(__)m
tanakashouzoux

2020/06/14 22:09

think49さん このコメントの流れにあった「関数は式を返しません。結果を返します。」の部分についてお伺いしたいのですが、入れ子になった関数はそのまま子のfunction(){};の塊を返すと思うのですが、これは結果(値?)と考えて宜しいのでしょうか?
think49

2020/06/14 23:17

markdownでは ">" の後ろに " " (半角スペース)が無ければ、引用と見なされません(blockquote要素でマークアップされません)。
tanakashouzoux

2020/06/15 00:00

think49さん こちらも大変失礼いたしましたm(__)m こちらも早速修正したいと思いますm(__)m
think49

2020/06/15 03:40

引用元「開眼!Javascript p101」直後のソースコードの行頭に ">" が見えます。 こちらも半角スペースが足りないと思います。
guest

回答4

0

実際に上記コードを私がコンソールで実行した所「undefined」と表示されてしまいました・・・

これだけ再現できなかったので、中途半端な回答かもしれませんが、


HTMLでsourceタグでソースコード書いて
Chrome Developer Toolsで調べたらわかるかと思いますが

1.このコードではまず即時関数

function() {
var count = 0;
return function() { // 子関数を返す
return ++count; // 変数 count は親関数で定義されている
};
}();
が書かれていて、即時関数なので書いた瞬間に実行され、その結果
「countUpFromZero」
には
「function() { // 子関数を返す
var count = 0;
return ++count; // 変数 count は親関数で定義されている
};」
が入っていると考えたのですが、これは間違っているのでしょうか?

countUpFromZeroには

ƒ () { // 子関数を返す return ++count; // 変数 count は親関数で定義されている }

これが入ります。

2.「関数countUpFromZero」を1回だけ「countUpFromZero();」で呼び出した時、

「countUpFromZero」
には
「function() { // 子関数を返す
var count = 0;
return ++count; // 変数 count は親関数で定義されている
};」
が入っているので、この無名関数が実行され、その結果
「countUpFromZero」
には
「count=1」
が入ると考えたのですがこれは間違っているのでしょうか?

上記回答のとおり、countUpFromZeroが入ってる内容を置き換えてください(count=1が入ってるのは正しいです)

3.2の考えがもし合っているのであれば上記コードのs「出力1、出力2、出力3」は間違っている気がするのですが、合っているのでしょうか?

var count = 0;の処理がないのでカウントは増えていきます。

投稿2020/06/14 08:40

編集2020/06/14 08:43
rururu3

総合スコア5545

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

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

tanakashouzoux

2020/06/14 11:17

rururu3さん わざわざご丁寧にありがとうございますm(__)m お陰様で理解が深まりました!!! 3つのconsole.log(countUpFromZero());のcountUpFromZero()には上から順に count=1,count=2,count=3 が入っているということで合っているのでしょうか??
rururu3

2020/06/14 11:26

入っていくっていうことになります。実質的にはcountUpFromZero()が呼ばれると前に呼ばれた値+1が帰るっていう考え方のほうがあってるかな
tanakashouzoux

2020/06/14 22:14

rururu3さん わざわざ何度もありがとうございますm(__)m お陰様で私の浅い理解が深まりました!!! 何度も挫折しては皆さんの様な優しい方々に助けて頂き本当にありがとうございます!
guest

0

1. 試せばわかります

JavaScript

1var countUpFromZero = function parent () { 2 var count = 0; 3 return function child () { return ++count; }; 4}(); 5 6console.log(countUpFromZero); // ƒ child () { return ++count; }

2. 関数は呼び出されるまで実行されません

JavaScript

1var count = 0; 2 3function increment () { 4 return ++count; 5} 6 7console.log(count); // 0 8increment(); 9console.log(count); // 1

上記と同様に、

JavaScript

1function parent () { 2 var count = 0; 3 return function child () { return ++count; }; 4} 5 6// parent,childともに呼び出されていない為、変数count は存在しない 7 8var countUpFromZero = parent(); // parentが呼び出される為、count === 0 (childは呼び出されていない為、インクリメントは発生しない) 9console.log(countUpFromZero()); // 1 (childが呼び出される)

3. 上記コードが不明

「上記コード」が何を指しているのか、不明です。

JavaScript

1var countUpFromZero = function() { 2var count = 0; 3return function() { // 子関数を返す 4return ++count; // 変数 count は親関数で定義されている 5}; 6}(); // countUpFromZero は呼ばれると即時実行し、無名関数を返す 7/* countUpFromZero() に返された子関数はその親関数の変数 count にアクセスする必要がある 8ため、それを保持する。countUpFromZero() を実行するたびに return ++count が実行される。 9*/ 10console.log(countUpFromZero()); // 出力:1 11console.log(countUpFromZero()); // 出力:2 12console.log(countUpFromZero()); // 出力:3

このコード全体を指していると仮定するなら、console.log()の評価値がundefinedだからです。

Chrome Developper Toolsはコンソールでコード実行時に、最後の文(Statement)の評価値を返します。

Re: tanakashouzoux さん

投稿2020/06/14 12:13

編集2020/06/14 12:46
think49

総合スコア18162

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

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

tanakashouzoux

2020/06/14 22:07 編集

think49さん わざわざご回答までありがとうございますm(__)m ネットで「return 変数 javascript」等で調べても該当する記述を見つけられなかった(関数とreturnの関係について述べたものは沢山あるのですが・・・)のでお伺いしたいのですが、変数をreturnするとその変数に保持されている数値を返すのでしょうか? consoleで試してみたところ変数に保持されている数値が返ってきたのですが、これが合っているのか偶々何かの偶然でそうなったのかの判断がつかず一度お伺いしたいと思った次第ですm(__)m
think49

2020/06/14 23:27

[修正依頼] 欄より質問者のコメントを引用します。 > think49さん > このコメントの流れにあった「関数は式を返しません。結果を返します。」の部分についてお伺いしたいのですが、入れ子になった関数はそのまま子のfunction(){};の塊を返すと思うのですが、これは結果(値?)と考えて宜しいのでしょうか? 関数式はJavaScriptパーサがパースした時、関数オブジェクト(new Function)に変化します。 今、問題とされているのは、文法(関数式)ではなく、実体を持ったオブジェクトです。 質問を [修正依頼] 欄でしないでください。 そこは回答者が質問者に指摘をする場です。 全体の質問は質問を編集して追記し、個別の質問は回答にコメントして対応すべきです。
tanakashouzoux

2020/06/14 23:59

think49さん 大変失礼いたしましたm(__)m 次回以降全体の質問は質問を編集して追記し、個別の質問は回答にコメントすようにしたいと思いますm(__)m
think49

2020/06/15 04:05 編集

> ネットで「return 変数 javascript」等で調べても該当する記述を見つけられなかった 全く同じ状況を探しても見つからないので、「個別の機能」を調べて、頭の中で組み合わせて下さい。 その例でいえば、「return文」と「関数」の2つです。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/return https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions そこに情報がなければ、「知りたい機能の名前」を確認して、検索し直して下さい。 > consoleで試してみたところ変数に保持されている数値が返ってきたのですが、これが合っているのか偶々何かの偶然でそうなったのかの判断がつかず一度お伺いしたいと思った次第ですm(__)m コード中のどの部分を指しているのか、分かりません。 私は関数を返している箇所が理解できてないように捉えて回答しましたが、別の場所がわかっていなかったのでしょうか。 そもそも、当初の3つの質問に対する解は理解出来たのでしょうか。 私の回答をどのように理解して、どこが分かりませんか。 いろいろ、わからないことが多くて、回答出来ません。
think49

2020/06/15 04:04

回答の > 3. 上記コードが不明 は、今も私にとっては、不明のままてす。
guest

0

難しく考えすぎでは?関数を実行すればreturnしたものが返っているので
それを正確に読むだけなような。無名関数を毎回変数に代入して書けば

javascript

1var p = function () { 2 var count = 0; 3 const c = function () { 4 return ++count; 5 }; 6 return c; 7}; 8 9var countUpFromZero = p(); 10 11console.log(countUpFromZero()); 12console.log(countUpFromZero()); 13console.log(countUpFromZero());

こんな感じだと思うので「countUpFromZero」に入るのはなにか考えるといいと思います。「undefined」になるというのはちょっとわかりませんね…console.log自体は返り値ないので「undefined」は出ると思いますがconsole.logの結果はその上に見えるはずなんですけどね

さらに

まだ余計なことを考えているようですのでもっと細かく変数に入れます。
console.log()はかっこの中身をコンソール表示する、それだけです。
こう書いてもまだ『console.logで「count=1」が表示されるはず』と思っているとしたら
言い方が悪いですが『質問する以前の問題』です。

javascript

1var p = function () { 2 var count = 0; 3 const c = function () { 4 count = count + 1; 5 return count; 6 //return ++count; 7 }; 8 return c; 9}; 10 11var countUpFromZero = p(); 12 13var ret1 = countUpFromZero(); 14// ret1には何が入っていますか? 15console.log(ret1); 16var ret2 = countUpFromZero(); 17console.log(ret2); 18var ret3 = countUpFromZero(); 19console.log(ret3);

投稿2020/06/14 09:04

編集2020/06/14 12:49
sousuke

総合スコア3828

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

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

tanakashouzoux

2020/06/14 11:15

sousukeさん ご回答ありがとうございますm(__)m お陰様でreturnのところ理解出来ました!!! console.log(countUpFromZero());のcountUpFromZero()には上から順に count=1,count=2,count=3 が入っていると思ったのですが、この認識で合っていますでしょうか??
sousuke

2020/06/14 12:38

『「count=1」が入っている』という表現がおよそほとんどの回答者に理解不能だと思います。 頑張って理解しようとすると『++count』は『count=count+1』でcountが0の時にcount=1とか そういう話かもしれませんがそんなことは関係ないです。 もう一度言いますがreturnしているものが返っているだけです。 「return 1」とあれば1が返ります。「return a」とあればaという変数の中身が返ります。 もう一度分解して編集しますのでそれを見てください。
tanakashouzoux

2020/06/14 22:12

sousukeさん ご丁寧にありがとうございますm(__)m そうなんです! 私の伺いたかったことがまさにそれです!!! 『「return a」とあればaという変数の中身が返ります。』というのを恥ずかしながら全然知りませんでした・・・ function(){};はこの形のまま返すのでcount=1もこの形のまま返すのではないかなどと考えてしまっておりました???? こんな初心者にも優しくご指導頂き本当にありがとうございますm(__)m
guest

0

回答は出ていますので、回答というより、感想になります。

開眼!Javascript p101

同書は持っていませんので、推測ですが、クロージャへの理解を深めるべき内容と思いました。

ご質問の内容からは、書籍内のサンプルコードを誤解されているように感じます。
(返却されたクロージャ内部で count が宣言されていると解釈しているようですが、違います)

修学目的でしょうから、無名関数を enclosure / closure と命名して、コードを眺めてみるのも良いと思います。

javascript

1var countUpFromZero = function enclosure() { 2 var count = 0; // enclosure 関数のスコープで宣言されている 3 4 return function closure() { 5 // 前置のインクリメント処理 6 return ++count; 7 8 }; 9}();

返却された関数(countUpFromZero() = closure())が実行されたとき、 内部で count前置のインクリメントになっている点に着目してください(返却の直前に加算される)。

  1. 2の考えがもし合っているのであれば

以下のように誤解したままだと、おっしゃるとおり、異なる結果になるでしょう。

javascript

1var countUpFromZero = function closure() { 2 var count = 0; // 書籍の内容とは異なるスコープで宣言 3 // 前置のインクリメント処理 4 return ++count; // 必ず 1になり、 undefined ではない(追記 5};

以上を踏まえて、 他の回答を読み返してみてください。

投稿2020/06/15 04:47

編集2020/06/15 04:51
AkitoshiManabe

総合スコア5432

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問