web-dev-qa-db-ja.com

JavaScriptで関数を宣言する

可能性のある複製:
Javascript:var functionName = function(){} vs function functionName(){}

関数を宣言するこれら2つの方法の違いは何ですか?

function someFunc() { ... }

var someFunc = function() { ... }

私は技術的な意味で質問していません。どちらが読みやすいのか、どちらのスタイルが好まれるのかは問いません。

88
nicholaides

私はここのほとんどの人々と異なる意見を持っています。 技術的には、この構文は関数を両方向で宣言するために同じことを意味する可能性があります最後のステートメントに誤りがあります。最後に追加します、なぜ);しかし、進化するパターンで彼らが果たす役割は膨大です。 Doughlas Crockfordによる「Javascript:The Good Parts」を強くお勧めします。

しかし、微妙で簡単な方法で私の主張を証明するために。ここに小さな例を示します。

//Global function existing to serve everyone
function swearOutLoud(swearWord) {
    alert("You "+ swearWord);           
}
//global functions' territory ends here

//here is mr. spongebob. He is very passionate about his objects; but he's a bit rude.
var spongeBob = {
    name : "squarePants",
    swear : function(swearWord) {
                name = "spongy";
                alert("You "+ swearWord);
                return this;
            }
}

//finally spongebob learns good manners too. EVOLUTION!
spongeBob.apologize = function() {
    alert("Hey " + this.name + ", I'm sorry man!");
    return this;
}


//Ask spongebob to swear and then apologize in one go (CASCADING EFFECT!!)
alert(spongeBob.swear("twit").apologize());

上記のコードを見ると、swearOutLoudという名前の関数を宣言しています。これは、任意のオブジェクトまたは呼び出しからWordを誓い、出力を提供します。渡される「this」パラメーターと引数を使用して、任意のオブジェクトに対して操作を実行できます。

ただし、2番目の宣言は、「spongeBob」というオブジェクトの属性として宣言されます。これは注意することが重要です。ここでのように、私はオブジェクト駆動型の動作に向かっています。私が返すものが他にない場合、「これ」を返すため、「カスケード効果」も維持しています。

Jqueryでも同様のことが行われます。フレームワークなどを記述しようとする場合、このカスケードパターンは重要です。 Builderデザインパターンにもリンクします。

しかし、オブジェクトの属性として宣言された関数を使用すると、より良いプログラミングパラダイムにつながるオブジェクト中心の動作を実現できます。うまく設計されていない場合。グローバルアクセスを使用して外部で宣言された個々の関数は、非オブジェクト指向のコーディング方法につながります。私はなんとか後者を好む。

カスケードの効果を確認するには、スポンジボブに一度に誓い、謝罪するように頼むことができる最後のステートメントを見てください。謝罪は後で属性として追加されましたが。

自分の主張を明確にしたいと思います。技術的な観点からの違いは小さいかもしれません。しかし、設計とコードの進化の観点から見ると、それは巨大であり、世界を変えます。

しかし、それは私だけです!それを取るか、それを残す。 :)

編集:

したがって、両方の呼び出しは技術的に異なります。名前付き宣言はグローバル名前空間に関連付けられており、解析時に定義されるためです。そのため、関数が宣言される前でも呼び出すことができます。

 //success
 swearOutLoud("Damn");

function swearOutLoud(swearWord) {
    alert("You " + swearWord)
}

上記のコードは適切に機能します。しかし、以下のコードはそうではありません。

swear("Damn!");
    var swear = function(swearWord) {
    console.log(swearWord);
}
48
Priyank

function someFunc() { ... }を使用する利点の1つは、関数名がFirebugデバッガーに表示されることです。他の方法で宣言された関数(var someFunc = function() { ... })はanonymousとして現れます。

14
Igor Zevaka

実際、違いは、2番目の宣言により、このような関数を宣言する機能が与えられ、オブジェクトのプロパティとして関数を使用できるようになることです。

var myObject=new Object();
myObject.someFunc=function() { ... }; 
5
Soufiane Hassou

スタイルの面では、2番目の例は、関数を宣言する他の一般的な方法とより一貫性があるため、読みやすいと主張できます。

this.someFunc = function() { ... }
...
someFunc: function() { ... },

ただし、前述のとおり、匿名であるため、プロファイリング時に名前は表示されません。関数を宣言する別の方法は次のとおりです。これにより、両方の長所を活用できます

var someFunc = function someFunc() { ... }
5
frglps

最初の形式は次のとおりです。

function test() { }

はより認識されている構文であり、2番目の形式は次のとおりです。

var test = function() { ... }

関数のスコープを制御することができます(varを使用することにより、とにかくグローバルになります)。

そして、あなたは両方をすることさえできます:

var test = function test() { ... test(); ... }

これにより、2番目の形式で再帰関数を定義できます。

2
EMK

もう1つの違いは、ほとんどのブラウザでは、後者は状況に応じて異なる実装を定義できるのに対し、前者はできないことです。クロスブラウザイベントサブスクリプションが必要だとします。このようにaddEventListenerTo関数を定義しようとした場合:

if (document.addEventListener) {
    function addEventListenerTo(target, event, listener) {
        ....
    }
} else if (document.attachEvent) {
    function addEventListenerTo(target, event, listener) {
        ....
    }
} else {
    function addEventListenerTo(target, event, listener) {
        ....
    }
}

一部のブラウザでは、すべての関数が解析され、最後の関数が優先されます。結果:上記は機能しません。ただし、変数への匿名関数の割り当ては機能します。変数に割り当てられた匿名関数を使用して、機能的および基本的な アスペクト指向プログラミング テクニックを適用することもできます。

var fib = memoize(function (n) { 
    if (n < 0) return 0;
    if (n < 2) return 1;
    return fib(n-1) + fib(n-2); 
});

...
// patch the $ library function
if (...) {
    $ = around($, fixArg, fixResult);
}
2
outis

読みやすくするために、最初の方が明らかに優れていると思います。将来のメンテナンスプログラマは、javascriptに精通していて、このスレッドで発生する細かい点の多くを知っているとしても、最初の形式を想定しています。

たとえば、Ctrlキーを押しながらfキーを押して関数の定義を検索し、そこで起こっていることを確認する必要がある場合、最初にsomeFunc = function()またはfunction someFunc()を検索します?

また、(私たちは読みやすさを話しているので)それについてなんとか活字体にするために、読者はしばしばテキストをすばやくスキャンし、関数定義を探している場合は「var」で始まる行をスキップする傾向があります。

これは非技術的な答えであることは知っていますが、人間がコンピューターよりもコードを読むのは難しいです。

1
Paul Degnan

書くとき

function Test() {
}

JavaScriptは、実際に呼び出された関数オブジェクトに割り当てられるプロパティを実際に作成します。このオブジェクトは、関数定義で報告されたコードを実行します。プロパティは、オブジェクトwindow、または関数定義を含むオブジェクトに添付されます。

1
kiamlaluno