4

「JavaScript の再紹介」を読んで、関数について興味深いことに気付きました。

上記のように無名関数に提供される名前は、関数自体のスコープでのみ使用できます (または少なくとも使用できるはずです)。

nodejs プロンプトでチュートリアルのコードに基づいていくつかのことを入力すると、ノードが作成者と一致していることを確認できました。

function add(foo, bar) {
  return foo + bar;
}

add(1, 2);

私を取得します 3、そして:

var five = (function plus(foo, bar) {
             return foo + bar;
           })(2, 3);
plus(2, 3);

plus が定義されていないという構文エラーが表示されます。

両方の関数を定義するために使用したコードは (名前を除いて) 同じだったので、少し混乱しています。JavaScript は、最初の関数が通常の関数で、2 番目の関数が名前付き無名関数であることをどのように認識しますか?

4

1 に答える 1

7

1 つ目は、通常の関数宣言です。宣言された名前は現在のスコープに導入され、暗黙的に関数本体を参照します。この形式でfunctionは、 はstatementであり、値を返しません。

2 つ目は関数式であり、代入の右辺の一部であり、中括弧で囲まれているため、インタプリタはそれを認識します。function他の「値」(または「式」)が提供された可能性がある場所に単語が表示されるときはいつでも、あなたが持っているのは関数式です。その式の結果は、関数本体への参照です。

関数式の名前 (指定されている場合) は、リンクで説明されているように、関数でのみ使用できます。

私見そのリンクの命名法は正しくありません。彼らが「名前付き無名関数」と呼んでいるものは、私の見解では「名前付き関数式」と呼ばれるべきです。この明らかなエラーは、すべての無名関数が実際には関数式であるという事実に起因する可能性がありますが、すべての関数式が無名というわけではありません。

このスタイルを使用する場合は、次のことに注意してください。

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

上記のようbarに、関数式があり、その結果が変数に代入されますfoo。名前barは現在のスコープには入れられませんが、関数自体の中で使用できます。

変数の宣言はfooスコープの先頭に引き上げられますが、上記の行が実際に実行されるまで、その値 (つまり、関数式への参照) は割り当てられません。

違いのもう 1 つの興味深いデモンストレーションは次のとおりです (Chrome コンソールから):

> function() { }
SyntaxError: Unexpected token (
> a = function() { }
function () { }

唯一の違いは、後者には への割り当てがあることに注意してくださいa。言語の文法では、関数ステートメントに関数のラベルを含める必要があるため、ステートメントを使用して無名関数を宣言しようとする試みは不正です。ただし、後者は暗黙的に関数式であり、匿名にすることができます。

于 2012-08-22T20:43:28.463 に答える