まずいきなりですが、JavaScript、全てが関数であり、クラスです。
var str = "hello";
は以下のように書き換えられます。
var str = new String("hello");
そして全ての関数はクラスとなります。
クロージャを使った形だと
var myClass = function () {
this.hello = function () {
alert("hello");
}
}
var instance = new myClass ();
instance.hello(); //hello
prototypeを使った形だと
var myClass = function () {}
myClass.protorype.hello = function () {
alert("hello");
}
var instance = new myClass();
instance.hello(); //hello
とすることもできます。
このあたりもクロージャとprototypeの違いがあるらしいんですが本題ではないので割愛。
ってかよくわかってない。
もうちょっと寄り道します。
JavaScriptではnewするとインスタンスになります。
つまりJavaScriptは全て関数で、newというのは、インスタンスを作るということ。
classというものはなく、逆にいうと全部クラスなので特にclassと定義することはありません。
“”,(),{}はnew String(),new Array(),new Object()の略。
さらにnewしたものはインスタンスなのでさらにnewすることはできません。
だから
var str = "hello"; var instance = new str();
とはできません。
またnewすると中身が実行されます。
これがコンストラクタとなります。
一方でjavascriptの関数の実行方法は二通りあります。
foo();
(foo)();
二通りある理由がよくわかりませんがとりあえず二通りあります。
寄り道の寄り道をすると()はArrayということだったので以下のような関数を実行してみたんですが、
function func1 () {
alert("function 1");
}
function func2 () {
alert("function 2");
}
(func1,func2)();
結果は「function 2」となりました。このあたりが謎。
話を少し戻します。
関数では名前をつけることができます。
また、変数に関数を詰め込むことができます。
関数に名前をつけたパターン。
function myFunc () {
alert("myFunc");
}
変数に関数を詰め込んだパターン
var myFunc = function () {
alert("myFunc");
}
この二つの違いは結構簡単で、関数に名前をつけたパターンは、スクリプト実行の最初に定義されます。
つまり以下はエラーになりません。
myFunc();
function myFunc () {
alert("myFunc");
}
逆に変数に関数を詰め込んだパターンだと以下はエラーになります。
一応先にvarで定義してもエラーになります。
var myFunc;
myFunc();
myFunc = function () {
alert("myFunc");
}
こうするとうまくいきます。
var myFunc;
myFunc = function () {
alert("myFunc");
}
myFunc();
じゃあこの変数に詰め込んだ関数とはなんでしょう。
言葉を使い簡単に説明すると無名関数といいます。
名前をもって生まれたものと、生まれたあとで名前をつけられたものの違いですね。
もちろん、無名関数でないものも変数につめることはできます。
var myFunc2 = myFunc;
function myFunc () {
alert("myFunc");
}
以上をふまえて new function() {} と (function(){})() の違いを説明します。
やっと本題なんですが、この記事だけみると逆に上の二つは明らかに違うのが分かると思うんですが、実は挙動としてはほぼ一緒なんです。
簡単に言うと、「即実行される関数」という感じです。
キーワードになるのが無名関数。
function () {}
これを単純に無名関数じゃなくすると
function someFunction () {}
という風になります。
someFunctionという名前にしました。
それをそれぞれnewや()()で呼び出してみると
new function () {}
つまりこれは
new someFunction();
となり
(function () {})();
こっちは
(someFunction)();
となります。
newはインスタンスとして実行するということ。
()()は関数呼び出しでした。
newの場合は無名関数クラスをnewしていて、そのコンストラクタが実行されています。
だから即実行されていました。
()()の場合は、もともと関数を実行するという意味。
つまりクラスとして使う場合はnew。
関数を即実行する場合は()()を使うということになります。
この二つが実際にどう影響をあたえるかというと、newはインスタンスになるのでthisのフォーカスがインスタンスになります。
対して()()の場合はインスタンスでもなんでもないので、親のthisを継承します。
個人的にはnew function(){}派なのですが、どうやら(function(){})()派も多いみたいです。
でも、ここらへんが分かってればどっちでも大丈夫そうです。
長いメモになってしまった。
去年もこのあたりについて調べたんですがようやく理解できました。
プログラムって大変。パソコン偉い。