疑問
即時関数は、即時実行できるが、結局関数は、下記例だとどこで実行している?
return result;は返り値として、関数の処理結果を変数resultに渡す、教えるということ?
即時関数と無名関数の違い(function()のようにfunction自体を()で囲まない、})の後に引数がある。のみ?いまいち違いが判らない。
下記の認識で間違っているところがあれば教えてください。
*関数 名前をつけて何度も使いまわす場合に選択する。
関数とは同じ処理を定義し、何度も使い回しができるかたちにしたもの
特徴
・変数に関数の定義そのものを = で直接入れることができない。変数の中で関数の定義作業を行えない。
・定義した関数はスコープ外で、呼び出しをしないと実行できない。
・変数に名前を付けないといけない。
例
<script> function sum(a,b){ var result = a + b; return result; } var answer = sum(1,2);//引数をスコープの外に記載し、わざわざ関数SUMに引数を渡さないといけない console.log(answer);//定義した関数の呼び出しをしないと定義した関数が実行できない。 </script>関数の呼び出しは、sum(1,2);ように、関数名();とすれば呼び出し実行ができる。
上記であれば、console.log(answer);でインスペクタのコンソールログに表記と、関数の呼び出し変数anwerを両方いっぺんに行っている。
*無名関数 1回きりしか使わない関数
特徴
・変数に関数の定義そのものを = で直接入れることができる。変数の中で関数の定義作業を行える。
・定義した関数はスコープ外で、呼び出しをしなくても、即時実行できる。
・変数に名前をつける必要がない。
・即時関数は無名関数の一種
・名前がないので何度も使いまわす事ができない。
例 関数名がない
<script> var sum = function (a,b){//変数に関数の定義そのものを = で直接入れることができる。ここに関数名SUMがない。 var result = a + b; return result; } var answer = sum(1,2);//引数をスコープの外に記載し、変数に引数を渡している。関数SUMに引数を渡している名前のある関数とは違う。 console.log(answcer); </script>*即時関数 関数定義と関数呼び出しをセットにしたもの
特徴
・変数に関数の定義そのものを = で直接入れることができる。変数の中で関数の定義作業を行える。
・定義した関数はスコープ外で、呼び出しをしなくても、即時実行できる。
・変数に名前をつける必要がない。
・即時関数は無名関数の一種
・名前がないので何度も使いまわす事ができない。
・無名関数と違い(function()のようにfunction自体を()で囲む。})の後に引数がある。
例
<script> var sum = (function (a,b){//変数に関数の定義そのものを = で直接入れることができる。ここに関数名がない。 var result = a + b; return result;//ここで変数を呼び出している? })(1,2);//この時点ですでに実行している。ここに引数を記載できる。 console.log(sum);//これは実行ではなくコンソールに表記しているだけ。 //var answer = sum(1,2);という定義した関数の呼び出しが、ここに、上記二つはあるがこちらはない。 </script>気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
横やりになってしまいますが代わりに続きを説明します。
まず「即時関数」という言葉の定義ですが、私は「関数を定義と同時に実行すること」と解釈しています。ですので「即時関数」自体は関数ではありません。
即時関数で使う関数を囲う「()」は、関数定義文と区別をする目的で付加します。区別すればいいので「()」でなくともよいのです。
例えば
(function (){console.log("!")})();
は
こうでも構いません。
!function (){console.log("!")}();
+function (){console.log("!")}();
-function (){console.log("!")}();
~function (){console.log("!")}();
即時関数の中で使用する関数は、無名関数である必要はありませんし、何度も使いまわすことも可能です。こんな書き方をすることはまずありませんが、JavaScriptの仕様として以下のようにも書けます。
(s = function x(){console.log("!")})()
「x」という名前の関数を変数「s」に代入して、即時実行しています。ですので即時関数と言えます。ですが、あとで「s()」を実行して使いまわすこともできます。また「a.name」で関数の名前を確認すると、「x」であることが確認できます。
つまり、即時関数はの中身の関数は無名関数である必要はありませんし、あとで使いまわすこともできるのです。
https://techacademy.jp/magazine/5530
の記事は残念ながら理解の浅い人が書いた文章なのだと思います。明らかに間違っています。
そんなどこのだれが書いたかわからないような情報はあまり信用せず、オライリーのJavaScriptかEffective JavaScriptなど信頼のできる書籍で勉強をした方がいいですよ。
そしてJavaScriptの仕様のこういう細かく深い部分は広範囲にわたります。きちんと勉強する前に、とりあえずわからないところを1つ1つ質問していても理解するのに何年もかかると思います。
オライリーのJavaScriptかEffective JavaScriptなどを最低一度、できれば3回程度繰り返し読み、そのうえで分からない部分を質問するようにした方がいいと思いますよ。
投稿2016/12/23 02:23
総合スコア902
0
下記の認識で間違っているところがあれば教えてください。
・変数に関数の定義そのものを = で直接入れることができない。変数の中で関数の定義作業を行えない。
微妙です。たとえば、
javascript
1var func = function notFunc(){};
これはエラーにならない。なぜなら関数定義ではなくて関数式になっているから。
上記であれば、console.log(answer);でインスペクタのコンソールログに表記と、関数の呼び出し変数anwerを両方いっぺんに行っている。
間違いです。そのコードではanswerには3が入っていますので、コンソールに表示してるだけ。
無名関数 1回きりしか使わない関数
間違いでは。
・名前がないので何度も使いまわす事ができない。
間違いだと思う。
即時関数は無名関数の一種
名前のある関数も即時実行できるので間違いかと。
javascript
1void function Func(){}();
・無名関数と違い(function()のようにfunction自体を()で囲む。})の後に引数がある。
間違いとは言えないですが、かっこは必須ではないので、微妙です。
投稿2016/12/22 08:02
総合スコア36115
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/22 09:35
2016/12/22 09:52
退会済みユーザー
2016/12/22 12:11
退会済みユーザー
2016/12/22 12:37
0
ベストアンサー
基本
関数宣言
function 関数名(){ }
実行するには
関数名();
関数は変数に入れれる
var 変数 = function 関数名(){};
変数にいれた関数を実行する
変数();
即時関数
関数宣言と同時に実行させるテクニックの事
( function 関数名(){} )();
こう書くだけ。
※書き方はこれだけではないですが、この書き方が一般的なのでこの形を覚えるだけでよいです。
即時関数を使う理由は、関数宣言後に即実行する場合、纏めてかけるため可読性がよいという点です。
Javascript
1function hoge(){ 2 : 3} 4 5hoge();
宣言と実行がバラバラなのを
Javascript
1(function hoge(){ 2 : 3}();
このようにまとめて記述でき可読性があがります。
ただのテクニックなので無くても困らない。
無名関数
関数名を省略したものを、関数名が無いので無名関数といっているだけです。
即時関数や関数を変数にいれて実行する場合など、関数名無くても問題ない時に使います。
Javascript
1// 即時関数の例(関数名あり) 2(function hoge(){ 3 : 4})(); 5 6// 即時関数の例(無名関数) 7(function(){ 8 : 9})();
とか
Javascript
1// 引数valに関数をもらって実行 2function xxxx(val){ 3 val(); 4} 5 6// xxxx関数の引数に関数を渡す(関数名あり) 7xxxx(function hoge(){ 8 : 9}); 10 11// xxxx関数の引数に関数を渡す(無名関数) 12xxxx(function(){ 13 : 14});
追記
無名関数 1回きりしか使わない関数なの?
引用テキスト無名関数の呼び出しは関数名でできないので、関数自体を変数に入れて変数名で呼び出すか、 即時関数にして呼び出さないといけない。
ご自身で記載している上記通りで、変数に入れておけばその変数で何度でも呼び出せます。
var answer = sum(1,2);のansertの中身は何?
sum(1,2)の形をみてください。
これは私が記載した関数を実行する形です。
よって、answerには関数sumの実行結果(return)が入ります。
即時関数は無名関数の一種ではないの?
即時関数と無名関数に何ら関わりはありません。
もう一度記載しますが、
即時関数とは、関数宣言と同時に関数を実行するテクニックであり
無名関数とは、関数名を定義しない事です。
ただ、即時関数は関数の宣言と同時に即実行するので関数名を定義しない事がおおいので
その事をいっているものと思いますが、即時関数と無名関数に関わりはありません。
即時関数とは関数を()で囲んで)の後に引数を指定すれば即時関数?
Javascript
1(function(){})(引数)
基本そうです。
少し難しい話なので、最初の回答ではあえて記載しませんでしたが、
javascriptにはfunction文(以下文)とfunction式(以下式)があります。
function 関数名(){} このような関数宣言は文となります。
文の特徴は関数の巻上げが行われます。
関数の巻上げとは、どこで宣言してもその宣言を先頭で宣言したものとして扱います
ですので、このように関数宣言より前にその関数を実行しても問題なく実行できます
Javascript
1hoge(); 2 3function hoge(){ 4}
では、関数文を即時関数にするために関数宣言の後に()で呼び出して見るとどうなるか
Javascript
1var a; 2 3a = 1; 4 5function hoge(){ 6} (); // ここで即時関数にしようとして、関数宣言の後に()を付けて呼び出す
これだけではJavascriptはhoge関数を文として認識するため
関数の巻上げが起こり、以下と同等の扱いになり、()が意味不明なものになります
Javascript
1function hoge(){ // 関数の巻上げで先頭で宣言されたものとされる 2} 3 4var a; 5 6a = 1; 7 8(); // ()だけ残り意味不明な状態となる
その為、関数の巻き上げが行われない式として認識させる必要があります。
その方法の一つが関数宣言を()で囲むことです。
(function() {})
これでこの関数を式として認識するので、実行させるため最後に()をつけて実行します。
(function() {})();
式として認識させる方法は()で囲む他色々ありますが。
人が見て一番分りやすい形が()で囲む方法なので、この形が使われています。
余談ですが、uglifyなんかすると()だと2文字使用するので!が使われる事が多いです
!function(){}()
投稿2016/12/22 13:36
編集2016/12/23 07:10退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/12/23 01:33
退会済みユーザー
2016/12/23 04:09
退会済みユーザー
2016/12/23 04:56
退会済みユーザー
2016/12/23 07:11
退会済みユーザー
2016/12/23 09:14
退会済みユーザー
2016/12/23 11:38
退会済みユーザー
2016/12/23 13:05
退会済みユーザー
2016/12/24 13:14
退会済みユーザー
2016/12/25 00:02
退会済みユーザー
2016/12/25 02:04
退会済みユーザー
2016/12/25 03:35
退会済みユーザー
2016/12/25 04:19
退会済みユーザー
2016/12/25 04:49
退会済みユーザー
2016/12/25 05:10
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/12/23 02:58