簡體   English   中英

關於JavaScript構造函數和匿名函數的一些問題

[英]A few question regarding JavaScript Constructor and Anonymous functions

我有以下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(){}(); 不能分配給其他變量?

  1. new關鍵字創建Console對象的實例,然后可以調用Log方法。 如果你直接調用Console() ,你將得到該函數的返回值。 在你的情況下,沒有,所以undefined 此外,如果您不使用new關鍵字,則在“類函數”中this分配的任何內容都將污染全局范圍。 因此,您不必將方法分配給this ,而是必須使用您將返回的代理對象

  2. 在您的示例中,您將logger變量分配給調用匿名函數的返回值 同樣,它不會返回任何內容,因此調用new logger()將無法工作,因為您無法實例化undefined 因此,刪除尾部()從匿名函數將分配功能logger ,而不是它的返回值,然后你就可以用實例化new (您也可以再次使用代理對象)。

在上面的兩個例子中,我強烈建議使用new關鍵字而不是創建和返回代理對象。 這利用了Javascript內置的實例化機制和函數原型鏈,並且比對象創建快得多

John Resig的這篇博客文章值得一讀,以獲取有關“類”實例化如何在Javascript中工作的更多信息: http//ejohn.org/blog/simple-class-instantiation/

當你執行function(){}()你正在定義並立即調用一個函數,正如你所指出的那樣。 因此當你有這個:

var logger = function(){}();

您將logger指定為該函數的返回值 ,而不是函數本身。 在您的示例中,函數不返回任何內容,因此logger將是未定義的。

就像樣式一樣, 在編寫立即調用的匿名函數時,將函數包裝在括號中是非常標准的:

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

這只是讀者的一個視覺暗示,你將要調用該函數,它可以節省很多混亂。 實際上,在某些情況下執行此操作非常重要:請參閱下面的注釋!

答案1:

您將'Log'功能添加到'this'中。 這就是您必須先從Console功能創建對象才能訪問它的原因。

當你執行Console()。Log()時,你試圖運行Console函數並在返回的對象上調用'Log'方法。 因為Console函數不返回任何內容,所以它是“未定義的”,因此您無法訪問Log方法。

答案2:

'logger'不是函數,而是匿名函數輸出的結果。

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

您的匿名函數不會返回任何內容,因此logger將“未定義”。 對於未定義的對象,沒有“log”方法。

要解決此問題,請執行以下操作:

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';

'this'將是'window'對象,它將添加'name'屬性,其值為'Console'。

如果你調用上面的函數,

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

JavaScript將創建一個新對象,可以使用“Console”中的“this”進行訪問。 現在輸出將具有'name'屬性。

如果上面沒有為您清理事情,請告訴我。 您必須了解它才能利用JS提供的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM