3

JavaScriptのモジュールの2つの宣言の違いは何ですか?1つは関数の周りに括弧があり、もう1つはそうではありませんか?

ある記事によると

無名関数の周りの()に注意してください。トークン関数で始まるステートメントは常に関数宣言と見なされるため、これは言語で必要です。()を含めると、代わりに関数式が作成されます。

チェックすると、どちらも同じことをするようです。

var person = (function () {
    // Private
    var name = "Robert";
    return {
        getName: function() {
            return name;
        },
        setName: function(newName) {
            name = newName;
        }
    };
}());

var person = function () {
    // Private
    var name = "Robert";
    return {
        getName: function() {
            return name;
        },
        setName: function(newName) {
            name = newName;
        }
    };
}();
4

3 に答える 3

4

JavaScript の関数には、宣言と式の 2 種類があります。

両者の違いは次のとおりです。

  1. 関数宣言が巻き上げられます。これは、JavaScript の宣言が巻き上げられるので、プログラムに現れる前に関数を呼び出すことができることを意味します。
  2. 関数式はすぐに呼び出すことができます。関数宣言はできません。これは、式が値を表す(または値を返す) ためです。関数式は関数を表現します。

関数宣言の例:

foo("bar");

function foo(bar) {
    alert("foo" + bar);
}

fooは関数宣言なので、上記のプログラムは動作します。

foo("bar"); // throws an error, foo is undefined - not a function

var foo = function (bar) {
    alert("foo" + bar);
};

上記のプログラムは、 as としてfoo宣言されundefined、巻き上げられ、後で関数式の値が割り当てられたままでは機能しません。したがってundefined、それは呼び出されたときです。

関数式の例:

(function (bar) {
    alert("foo" + bar);
}("bar"));

上記の関数は関数式であるため、すぐに呼び出されます。

function (bar) {
    alert("foo" + bar);
}("bar"); // throws an error, can't call undefined

上記の関数は関数宣言であるため、すぐには呼び出されません。宣言は表現 (または値を返す) ではないことに注意してください。undefinedつまり、関数として呼び出そうとするようなものです。

関数はどのように式になりますか?

式が期待されるコンテキストで関数が使用されている場合、それは式として扱われます。それ以外の場合は、宣言として扱われます。

次の場合に式が期待されます。

  1. 変数に値を代入しています (つまりidentifier = expression)。
  2. 括弧内 (つまり( expression ))。
  3. 演算子のオペランドとして (つまりoperator expression)。

したがって、以下はすべて関数式です。

var foo = function () {};
(function () {});
~function () {};

それ以外はすべて関数宣言です。つまり、関数の前に何もない場合、それは宣言です。

このコードを参照してください: https://github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94

次の関数isExpressionは、任意の JavaScript コードが式であるかどうかをテストするために使用されます。

function isExpression(code) {
    if (/^\s*function\s/.test(code)) return false;

    try {
        Function("return " + code);
        return true;
    } catch (error) {
        return false;
    }
}

これであなたの心の疑問が解消されることを願っています。

要するに:

  1. 関数式は、値 (この場合は関数) を表現または返します。したがって、すぐに呼び出すことはできますが、プログラムに表示される前に呼び出すことはできません。
  2. 関数宣言が巻き上げられます。したがって、プログラムに表示される前に呼び出すことができます。ただし、値を表現しないため、すぐに呼び出すことはできません。
于 2013-02-22T12:14:11.417 に答える
1

違いは、次のように書くときです。

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

(余分だが便利な) グループ化の使用は()、右側がすぐに呼び出される関数式 (IIFE) である可能性が高いことを最初の行と非常によく似たものから明確にするための一般的なコーディング スタイルです。ただし、2番目の場合:

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

かなり数行下の最後の行を読むまで、それは明らかになりません。最後の行に到達するまで、おそらく単純な割り当てを読んでいると思ったでしょう。

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

括弧は単純な割り当てでも使用できることに注意してください。

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

しかし、その場合、それらは本当に不要です (そして、IIFE にそれらを使用する慣習により、おそらく誤解を招く可能性があります)。

かっこの重要なペアを参照してください。

于 2013-02-22T11:56:59.530 に答える
1

現在のコンテキストでは、インタープリターに違いはありません。通常、モジュールを記述する好ましい方法は、関数を括弧で囲むことです。

var person = (function () {
    // Private
    var name = "Robert";
    return {
        getName : function () {
            return name;
        }
    };
}());

これは、構文が簡潔であり、関数が宣言された直後に関数を呼び出したいことが明らかだからです。もう1つの理由は次のとおりです。

(function () {
    //some stuff
}());

動作しますが

function () {
    //some stuff
}();

これはいけません。

通常は良いことである一般的なコーディングスタイルを使用するたびに関数をラップすることによって:-)。

于 2013-02-22T12:00:51.330 に答える