2

次の JavaScript コードを確認してください。

(function (w, d) {
    var loader = function () {
        var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0];
        s.src = "https://example.org/script.js";
        tag.parentNode.insertBefore(s,tag);
    };
    w.addEventListener ? w.addEventListener("load", loader, false) :
                         w.attachEvent("onload", loader);
}) (window, document);

このコードの作成者がこの方法を使用して、ドキュメントにスクリプトを含めたのはなぜですか? そして、この行の有用性は何ですか:

w.addEventListener ? w.addEventListener("load", loader, false) :
                     w.attachEvent("onload", loader);

最後のポイント: 私は JavaScript の初心者ですが(window, document)、最後の は何ですか?

4

10 に答える 10

3

window.addEventListener最初の質問は、コードが定義されているかどうかを確認することです。そうである場合はそれを使用し、そうでない場合はを使用しますwindow.attachEvent。これはブラウザの互換性のためです。

2番目の質問、このコードは2つのパラメーターwとdを受け取る無名関数です。この関数はすぐに呼び出され、パラメータwindowとを渡しますdocument

于 2012-04-09T01:00:24.840 に答える
2

まず、w.addEventListener ?ブラウザがwindowのaddEventListenerメソッドをサポートしているかどうかを確認します

第二に、(window, document)彼が以前に書いた無名関数の単なるパラメーター呼び出しですfunction(w,d) {}

于 2012-04-09T01:01:33.070 に答える
2

次の addEventListener 行は、ページの読み込みが終了したときに呼び出されるように関数を登録するためのものです。Internet Explorer と Firefox (その他) は、これを行うために異なる機能を使用します。

w.addEventListener ? w.addEventListener("load", loader, false) :
                 w.attachEvent("onload", loader);

JavaScript では、関数はそれ自体がオブジェクトです。そのため、「値」は変数に割り当てたり、すぐに消費したりできます。すぐに使用するには、括弧で囲み (そうしないと、目的の処理が行われません)、通常の関数のように呼び出します。

(function (w, d) { ... }) (window, document);

2 行に分割すると、何が起こっているかがより明確になります。

var a = function(w, d){ ... };
a(window, document);

グローバルスコープを一時的な値や関数で汚染しないようにするために、このように行われました。他の誰かの変数を破棄しないことは言うまでもありません。これは、次の 2 つの部分に分けることができます。

  1. コードをクロージャにカプセル化することにより、内部で明示的に宣言されたものはすべて、グローバル スコープではなく、クロージャのスコープ内にあります。var loaderクロージャーのスコープ内にあります。
  2. クロージャーをすぐに消費することにより、グローバルスコープの変数に格納されません。匿名で宣言されているため、グローバル スコープでは名前付き関数として存在しません。
于 2012-04-09T01:16:15.330 に答える
1

スクリプトタグを添付する前に、作成者がページが完全に読み込まれるのを待っているようです。addEventListener(DOMレベル2)とattachEvent(Microsoftのもの)は、イベントをアタッチするためのより柔軟な方法です。コードはと言っているのと似ていますw.onload = loader

最後のビットは、引数を無名関数に渡すことです。匿名関数では、引数に名前が付けられwますd。最後に()を付けると、匿名関数がすぐに呼び出されます。

于 2012-04-09T01:00:43.933 に答える
1

したがって、関数はクロージャにラップされます。これは、とを意味w = windowd = documentます。

メソッドが呼び出されると、呼び出される関数が作成されますloader。これは、2つの可能なイベントリスナートリガーのいずれかのコールバックです(つまり、ウィンドウでloadoronloadイベントが呼び出されたときに呼び出されます)。

x ? y : z構文は省略形の呼び出しif then elseです。

これを拡張すると、次のようになります。

if (w.addEventListener) {
  w.addEventListener("load", loader, false);
} else {
  w.attachEvent("onload", loader);
}

そのステートメントは、IEと他のブラウザーの両方のメソッドに対応するために使用されます。

于 2012-04-09T01:01:18.483 に答える
1

これは事実上次と同じです。

function RegisterEventListener(w, d) {
    var loader = function () {
        var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0];
        s.src = "https://example.org/script.js";
        tag.parentNode.insertBefore(s,tag);
    };
    if (w.addEventListener) {
       w.addEventListener("load", loader, false);
    } else {
       w.attachEvent("onload", loader);
    }
}

RegisterEventListener(window, document);

唯一の本当の違いは次のとおりです。

  1. 匿名関数を(を使用してfunction () {};)定義し、それを何にも割り当てない場合、それは限定的な使用にのみ使用できます(それを参照する方法がないため)。同時に、無名関数は(質問のコードにあるような)即時実行も可能にしますfunction(a, b) {}(a, b);
  2. condition ? true : false3次演算子)は単純なifステートメントを書くための省略形であるため、書き出すのに必要な入力は少なくて済みますが、読みにくいと考える人もいます。
于 2012-04-09T01:02:07.000 に答える
1

私は間違っているかもしれませんが、これは Google が分析スクリプトで使用する実装です。

これはクロージャーと呼ばれ、自動実行され、変数を内部に囲む関数であり、コードを台無しにすることはできません。

このコードは基本的に script タグを作成し、文書内で最初に見つかった script タグの前にこれを DOM に追加します。

最初の質問に対する答えは、ブラウザの互換性に関するものです。ブラウザによっては、ページ内の要素 (この場合はウィンドウ) にイベントをアタッチするために使用するものもあれば、ウィンドウのロード イベントで起動するものもあります (すべてのコンテンツがロードされたとき、ドキュメントの準備ができた後) addEventListenerattachEventより詳細な答えについては、これを見てください: window.onload vs $(document).read()

2 番目の答えは簡単です。これは、クロージャー (自動呼び出し関数) で使用されるパラメーターであり、次の方法で読み取ることができます。

function anonymous(w, d) {
    ...
}
anonymous(window, document);
于 2012-04-09T01:05:52.433 に答える
1

このコードの作成者は、クロージャにラップされた無名関数を使用して関数を起動し、ロード イベントを登録しています。ウィンドウの onload イベントが発生するまで、ページ上のスクリプトは実際には読み込まれません。

作成者がスクリプトのロードを遅らせている理由は、他のスクリプトで実際にロードする前に Web ページをレンダリングするためにより多くの時間を与えるためである可能性があります。これは、すぐに必要でないリソースの読み込みを遅らせながら、ページ コンテンツをすばやく読み込むための優れた手法です。

著者が使用している手法は、クロージャーにラップされた無名関数です。これを想像してください:

myFunction (window, document);

ここで、関数呼び出しを無名関数に置き換えます。

function(w, d) {
    // do stuff
    alert("w = " + w); 
    alert("d = " + d);
}

ここで、実際に名前を付けずに、その関数をすぐに実行します。また、その無名関数に 2 つのパラメーターを渡します。

( function(w, d) {
      // do stuff
      alert("w = " + w);
      alert("d = " + d);
})  ("1234", "5678");

この例の出力は次のようになります。

w = 1234
d = 5678

括弧に注意して一致させると、最初の外括弧が、関数名である文字 2 の最後の行の閉じ括弧と一致し、次の括弧のセットが、関数にパラメーターとして渡される 2 つの値をラップします。

これは、最初は理解するのが難しい概念です。それが数回行われるのを見た後、それはより理にかなっています。

于 2012-04-09T01:06:06.257 に答える
1
  1. このようにスクリプトを追加すると、作成者は HTML ファイルを直接編集しなくても、そのスクリプトをドキュメントに含めることができます。必要な場合にのみスクリプトを動的にロードするためにも使用できます。(つまり、ページ上で何かを編集するためのコードがたくさんある場合、ユーザーが実際に編集ボタンをクリックするまでダウンロードしたくないので、不要なときに帯域幅を浪費することはありません)。

  2. addEventListener と attachEvent は、ページの読み込みが完了したときに呼び出される関数をトリガーする方法です。この場合、という名前の関数がありloader ます。両方の理由は、一部のブラウザが一方をサポートし、一部のブラウザが他方をサポートしているためです。私はjQueryを長く使ってきたので、どれがどれだか覚えていません。

  3. (window, document) は、これらの変数をスコープ内にカプセル化したり、省略形の w および d でそれらを参照したりする方法です。作成者は、これらのパラメーターを期待する関数を作成し、window と document の両方を引数として渡します。

閉鎖は、作成者が自分のスクリプトがページ上の他のスクリプトと衝突するのを防ぐのにも役立ちます。そこで宣言されたすべての変数は、他の言語のプライベート変数のように考えてください。

于 2012-04-09T01:06:08.140 に答える
1

コードのwindow, document最初のブロックの最後にある は、コード ブロックの残りの部分で定義されている無名関数への引数です。Javascript はほぼ関数型言語であるため、プログラマーはこれらの匿名関数を定義し、名前を付けずに使用することさえできます。

疑問符を付けて貼り付けたコード ブロックは、次のパターンに適合する言語構造である中置表記の例ですcondition ? ifTrueExpression : ifFalseExpression。が真の場合condition、式全体は と等しくなりifTrueExpressionます。それ以外の場合、式全体は と等しくなりifFalseExpressionます。

貼り付けた中置記法の使用は、使用されているインターネット ブラウザーの種類を検出するのに一般的です。このコード ブロックがどのブラウザーを検出しようとしているかはわかりませんが、その目的は、ブラウザー固有の方法でイベント ハンドラーを実装することです。

于 2012-04-09T01:14:10.807 に答える