[英]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(){}(); 不能分配給其他變量?
new
關鍵字創建Console
對象的實例,然后可以調用Log
方法。 如果你直接調用Console()
,你將得到該函數的返回值。 在你的情況下,沒有,所以undefined
。 此外,如果您不使用new
關鍵字,則在“類函數”中this
分配的任何內容都將污染全局范圍。 因此,您不必將方法分配給this
,而是必須使用您將返回的代理對象 。
在您的示例中,您將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');
您必須要了解的主要事情是,在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.