11

私はJavascriptが初めてで、関数宣言の仕組みに混乱しました。私はそれについていくつかのテストを行い、いくつかの興味深い結果を得ました:

say();

function say()
{
    alert("say");
}

前方宣言が機能し、ポップアップが「言う」

反対側に

say();

say = function()
{
    alert("say");
}

関数オブジェクトも宣言しましたが、機能しませんでした

関数を宣言し、後で再宣言すると、次のようになります。

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

「話す」ではなく「言う」をもらいました。それは驚きです!

わかった。最新の関数宣言だけが動くようです。次に、最初に関数オブジェクトを宣言し、次に「通常の」関数を宣言します。

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

もう一つ驚いたのは、「speak」に続いて「speak」だったことです。「通常の」関数宣言はまったく機能しませんでした!

それらすべての説明はありますか?そして、「通常の」関数宣言が本当に「脆弱」であり、同じ名前の関数オブジェクトによって簡単にオーバーライドできる場合、それを避けるべきですか?

もう 1 つの質問は、関数オブジェクト形式だけでは、その前方宣言は不可能になるのでしょうか? Javascriptでそれを「シミュレート」する方法はありますか?

4

4 に答える 4

3

Javascriptは次のように機能します。

ドキュメントが解析されfunction、実際のステートメントが実行される直前に、宣言がすべて考慮されます。これが最初の例です。

関数をローカル変数に割り当てる場合、それは実行中に行われるため、2番目の例のメソッドを使用することはできません。

関数を2回宣言すると、最後の関数がアプリケーション全体で使用されるという経験があります。これが3番目の例です。

これらの関数はwindowオブジェクトのメンバーになり、事実上グローバルに宣言されます。関数の値にローカル変数を割り当てると、そのローカル変数がwindowオブジェクトのメンバーよりも優先されます。javascriptがローカル変数を見つけられない場合は、スコープ内を検索してそれを見つけますwindow。オブジェクトが最後の手段です。sayこれが最後の例で起​​こったことです。グローバル関数よりも具体的なスコープにある変数がありますsay

実行時に再宣言する場合say、つまり最後の例で宣言の順序を入れ替える場合は、予想される2つの異なるアラートが表示されます。

say(); //speak, the global function

function say() {
  alert('speak');
}

var say = function() {
  alert('say');
}

say(); //say, the declared local variable
于 2010-01-15T15:38:24.873 に答える
1
say();

function say()
{
    alert("say");
}

ここで、インタプリタsay()は呼び出されたときの定義をフェッチして実行します。

say();

say = function()
{
    alert("say");
}

ここでは、say()フェッチの定義はありません。代わりに、無名関数を変数に割り当てています。インタプリタは、前方宣言を見つけることができるように、これを「見つける」ことはできません。

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

ここsayで定義してから再定義します-最後の定義が優先されます。

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

これsayは無名関数を指す変数です(最初のステートメントが解釈された後)。これは、割り当ての前に関数定義を配置した場合と同じように、どの関数定義よりも優先されます。

しかし、あなたが持っていた場合

say();

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

次に、「言う」の後に「話す」が続きます。

于 2010-01-15T15:39:01.980 に答える
0

関数定義が順番に適用されることが期待できます。次に、関数オブジェクトの割り当てを含め、メソッド以外のすべてのコード行が順番に実行されます。これはあなたの例のそれぞれを説明します。しかし、それは興味深い問題です。関数オブジェクトを呼び出そうとした、それを割り当てることはできず、機能することを期待できます。ただし、実行可能コードに続く関数定義が実際に最初に適用されます。

于 2010-01-15T15:38:02.013 に答える
0

javascriptがそのように機能する場合でも、後で関数を呼び出すことは常に良い考えです。

ほとんどの言語はそのようには機能しませんが、代わりにこれを行います。

function say(){
    alert("say");
}

say();

また

say = function(){
    alert("say");
}

say();

また

(function(){
    alert("say");
})();
于 2010-01-15T15:46:52.607 に答える