10

John Resigのサイトから次の2つのURLを分析していますが、無名関数に名前を付けることがどのように違いを生んだのか理解できません。

私の理解では、無名関数に付けられた名前は関数定義内でのみ使用でき、関数定義の外部では使用できませんが、次のリンクでは大きな違いがあります

説明や参考資料は大いに役立ちます。

私はまだ#14の次の行と混同しています

var samurai = { yell: ninja.yell }; 
var ninja = {};
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." ); 

忍者が空白のオブジェクトを指しているときに、Samurai.yellメソッドがまだninja.yellを指すことができるのはどうしてですか。

#13と#14の唯一の違いは、#14の関数式に名前を付けることです。

ninja.yellはyellにコピーされ、参照されませんか、またはこれらの種類のNAMED関数式は、このようなシナリオでグローバルスコープを持ちますか?

同じことが#13と#14でも起こりますが、唯一の違いは、関数が#14で名前が付けられ、#13で名前が付けられていないことと、#14でninja = {}、#13でninja=nullであるということです。#14が機能し、#13が機能しなくなる、私が見逃しているNAMEDFUNCTIONEXPRESSIONSに関する隠された概念はありますか。

4

4 に答える 4

7

内部の例では、#13 の忍者オブジェクトへの追加アクセスをスキップできます。

匿名クロージャー (ninjaすでにそのコンテキストにいますが、オブジェクトへのアクセスが必要です):

var ninja = { 
  yell: function(n){ 
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  } 
};

名前付きクロージャは直接呼び出すことができます:

var ninja = { 
  yell: function yell(n){ 
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  } 
};

もう1つの利点は、名前付きクロージャーがスタックトレースを有効にすることです:

あなたがそうすると仮定します:

(function fooBar() { console.log(brazl); })();
// will create an error with "fooBar" in the stack trace instead of "anonymous function"

編集: オーバーヘッドのように見えるかもしれませんが、開発中のデバッグに役立ちます。たとえば、YUICompressor と Closure Compiler は、これらの名前が本質的に必要ない場合は削除できます。

于 2012-04-25T15:43:20.287 に答える
6

Kolink に好戦的になろうとしているわけではありませんが、彼はそれが良い例ではないと言い過ぎています。#14が(あなたが共有したリンクで)関係があるのは、名前付き関数式です(関数宣言とは別の動物です)。関数参照がどこに渡されるかに関係なく、関数式に名前を付けると、その関数内から自分自身を呼び出す方法が常にあります。関数式に付けるこの名前は、それだけが知っている名前です。外部スコープには存在しません。

関数式と関数宣言の詳細については、MDN のherehereを参照してください。一番下の 2 番目のリンクには、名前付き関数式に関する見出しがあります。用途があります。ローカル変数またはグローバル変数のスコープに何も追加しない、1 回限りの再帰関数の例については、私の Gistを参照してください (たとえば、1 回限りの DOM トラバーサルに役立ちます)。

また、Tobias (彼の回答はこちら) は、名前付き関数式の他の有効な使用法、つまりデバッグでの使用法を指摘しています。

于 2012-04-25T15:46:40.323 に答える
2

最初のケースでは、どのオブジェクトがそれを呼び出すかに関係なく、yellメソッドは にアクセスしようとしています。一方、2番目では、関数に名前が付けられているため、存在するものninja.yellを呼び出そうとします。yell

これは良い例ではありません。this.yellの代わりに を使用して、現在のオブジェクトからメソッドninja.yellを取得する良い例です。yell

于 2012-04-25T15:39:19.243 に答える
0

サイトhttp://kangax.github.com/nfe/は非常に参考になります。はい、関数式である限り、名前は内部でのみ使用でき (例: デモのように再帰呼び出しの場合)、name関数のプロパティを設定するため、デバッグ (例: スタック トレース) にも役立ちます。

于 2012-04-25T15:51:11.163 に答える