2

次の JavaScript 関数があります。

function Console() {
    this.Log = function(msg) {
        if (document.getElementById("console")) {
            var console = document.getElementById("console");
            console.innerHTML += msg + "<br/>";
        }
    }
}

質問 1: なぜ新しいキーワードを使用する必要があるのですか?

new Console().Log("hello world");

なぜこれができなかったのですか?

Console().Log("hello world without using new");

質問2:

var logger = function() {
    this.log = function(msg) {
        new Console().Log(msg);
        new Console().Log("log initialized");
    }

    this.log2 = function(msg) {
        new Console().Log(msg);
        new Console().Log("log2 initialized");
    }
}(); //notice the brackets

ロガーの末尾に () があるため、これは実行されません。

new logger().log("hello world");

末尾の () は、関数がすぐに呼び出されることを意味しますが、なぜ機能しないのでしょうか? function() {} (); からですか?他の変数に割り当てることはできませんか?

4

3 に答える 3

5
  1. newキーワードは、メソッドをConsole呼び出すことができるオブジェクトのインスタンスを作成します。Log直接呼び出すConsole()と、その関数の戻り値が何であれ取得されます。あなたの場合、何もないのでundefined. さらに、キーワードを使用しない場合、その「クラス関数」内にnew割り当てたものはすべて、グローバル スコープを汚染します。thisしたがって、メソッドを に割り当てる代わりに、代わりに返すプロキシ オブジェクトthisを使用する必要があります。

  2. あなたの例では、匿名関数を呼び出す戻り値loggerに変数を割り当てています。繰り返しますが、何も返さないため、インスタンス化できないため、呼び出しは機能しません。したがって、無名関数から末尾を削除すると、戻り値ではなく に関数が割り当てられ、 でインスタンスできます。(プロキシ オブジェクトを再度使用することもできます)。new logger()undefined()loggernew

上記の両方の例で、プロキシ オブジェクトを作成して返すのではなく、newキーワードを使用することを強くお勧めします。これは、Javascript の組み込みのインスタンス化メカニズムと関数プロトタイプ チェーンを利用し、オブジェクトの作成よりもはるかに高速です。

John Resig によるこのブログ投稿は、Javascript で「クラス」のインスタンス化がどのように機能するかの詳細について読む価値があります: http://ejohn.org/blog/simple-class-instantiation/

于 2009-08-28T00:43:34.993 に答える
2

答え 1:

「this」に「Log」機能を追加しました。これが、アクセスする前にコンソール機能からオブジェクトを作成する必要がある理由です。

Console().Log() を実行すると、コンソール関数を実行し、返されたオブジェクトで「Log」メソッドを呼び出そうとしています。Console 関数は何も返さないため、「未定義」であり、Log メソッドにアクセスできません。

答え 2:

「ロガー」は関数ではなく、無名関数出力の結果です。

E.g. var logger = function() { //your code; } ();

匿名関数は何も返さないため、ロガーは「未定義」になります。また、未定義のオブジェクトの場合、「ログ」メソッドはありません。

この問題を解決するには、次のようにします。

var logger = function() {
    var output = {};
    output.log = function(msg) {
        new Console().Log(msg);
        new Console().Log("log initialized");
    }

    output.log2 = function(msg) {
        new Console().Log(msg);
        new Console().Log("log2 initialized");
    }

    return output;
}();

To use, you can write,

logger.log('hello');

JS での関数とオブジェクトの作成について

理解しなければならない主なことは、JavaScript では、通常の関数が「new」キーワードで呼び出されると「コンストラクター」として機能するということです。

次の関数を検討してください。

function Console()
{
    this['name'] = 'Console'
}

このように上記の関数を呼び出すと、

   Console();
   alert(window.name); //alerts 'Console';

「これ」は「ウィンドウ」オブジェクトになり、「コンソール」の値を持つ「名前」プロパティを追加します。

上記の関数を次のように呼び出すと、

   var output = new Console();
   alert(output.name)  // alerts 'Console'

JavaScript は、'Console' 内の 'this' を使用してアクセスできる新しいオブジェクトを作成します。出力には「name」プロパティが含まれるようになりました。

上記で問題が解決しない場合はお知らせください。JS が提供する機能を利用するには、JS を理解することが不可欠です。

于 2009-08-28T00:44:03.573 に答える
2

function(){}()あなたが指摘したように、あなたがそうするとき、あなたはすぐに関数を定義して呼び出しています。したがって、これがある場合:

var logger = function(){}();

関数自体ではなく、その関数の戻り値loggerになるように割り当てています。あなたの例では、関数は何も返さないため、未定義になります。logger

スタイルの問題として、すぐに呼び出される無名関数を記述する場合、関数を括弧で囲むのは非常に標準的です。

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

これは、その関数を呼び出すことを読者に視覚的に示すだけであり、多くの混乱を避けることができます。実際、いくつかの状況ではそれを行うことがかなり重要です: 以下のコメントを参照してください!

于 2009-08-28T00:43:40.360 に答える