答案在UPDATE 2/ANSWER下面嵌入死鬥:自執行的匿名航班嗎功能的「新功能」
感謝約瑟夫幫助我找到答案(雖然我不喜歡它=) 。
原來的問題
雖然在JavaScript中使用Namepsaces時做的最佳做法的一些研究,我碰到這個定義中的「模型模式」的:http://yuiblog.com/blog/2007/06/12/module-pattern/。
自從我在YUI2多年前看到它以來,我一直在使用這種模式,本文給出了這個概念的一個很好的概述。但是它沒有涉及的是爲什麼使用「自動執行匿名函數」來代替「新函數」。評論中提到了這個問題,但作者沒有很好地描述。由於這篇文章是4歲以上(我沒有在網上找到答案),我想我會把它帶到這裏。
它已經在關閉,所以? (見:Why is this function wrapped in parentheses, followed by parentheses?其中也不回答我的問題=)。
假設下面的設置代碼..
var MyNamespace = window.MyNamespace || {};
這些這是優選的,爲什麼呢?
MyNamespace.UsingNew = new function() {
var fnPrivate = function() {
return "secrets1";
};
this.property = "value1";
this.method = function() {
return "property = " + this.property + ' ' + fnPrivate();
}
};
MyNamespace.UsingSelfEx = (function() { //# <- Added "pre-parens" suggested by chuckj
var fnPrivate = function() {
return "secrets2";
};
var fnReturn = {};
fnReturn.property = "value2";
fnReturn.method = function() {
return "property = " + this.property + ' ' + fnPrivate();
}
return fnReturn;
})();
UPDATE:
看來,像jQuery,所有時尚的年輕人使用的是 「自執行的匿名函數」(SEAF)!但我不明白這一點,因爲我發現在定義公開函數時使用.UsingNew方法會更清晰(而不是在需要單獨維護的返回值中,或者被迫使用內聯對象符號)。
爲不需要「即=這種」不爲我舉行的水有很多原因的說法:
- 爲了避免「無功即=這個」你最終要麼做一個「 var obj「加上一個return語句(必須保留公有的單獨定義)或被迫爲公共屬性/方法使用內聯對象表示法(返回{1,2,3})。
- 您可以在類/名稱空間的頂部始終創建一個「var that = this」的私有變量,並始終使用「that」。
現在......我想我的開發風格可能會使得.UsingNew模式更容易管理。我的「私人」功能本質上幾乎總是「靜態」的,所以我需要在上下文中傳遞(取代「this」)。我也養成了使用「縮寫」命名空間的習慣,所以當我確實需要訪問「this」時,我只需通過「縮寫」命名空間而不是通過它的完整路徑來引用完整對象。例如: -
var PrivateFunct = function() {
var rThis = Cn._.val; //# The abbreviated form of Cn.Renderer.Form.Validation
//...
};
,或者如果它是一個專用靜態函數...
var PrivateStaticFunct = function(oContext) {
//...
};
其他然後上面給出的原因,我個人覺得在.UsingNew方法多源更具可讀性。我有一個相當廣泛的代碼庫,它使用了.UsingNew模式:http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/和Validation functionality可能是最簡單的一個快速讀取通道。我也使用一些SEAF函數(請參閱ErrorMessages.js.aspx),但只有在它們有意義時才適用。
我無法想象必須維護單獨的回報以公開底部的公共接口!呸!
現在,請不要誤會我的意思,有很多地方SEAF對於強制關閉非常有用,但我個人認爲它在對象內過度使用。
更新2:
在進一步的思考(並感謝約瑟夫他的回答下的進一步討論)似乎是可以應用於此死鬥一些規則:
每道格拉斯·克羅克福德(參見:JS we hardly new Ya)匿名功能不應該用「新」的關鍵字,因爲:
- 這是更快地使用一個物體L iteral。
- 通過使用new來調用該函數,該對象將保留在無價值的原型對象上。這浪費了記憶,沒有抵消優勢。如果我們不使用新的,我們不會將浪費的原型對象保留在鏈中。 (注:原型來人來電構造函數定義後,和SEAF或「新」的匿名函數被解僱了一個迫在眉睫的不能使用的原型與他們)
- 它要求使用對象文本更少的代碼。 (雖然真的,但我不同意,因爲我討厭對象文字符號,我更喜歡使用;而不是,因爲它更可讀)。
- 將新的功能直接放在功能前面永遠不是一個好主意。例如,新函數在構造新對象時沒有優勢。
如此看來肉的事情土豆是這樣的:SEAF的是最好var obj = new function() {...};
由於速度和更少的開銷(沒有不必要的原型對象)。你必須承受的是,你被迫使用對象字面符號(所以,在你的公共成員之間,而不是);或者在返回對象中維護一個單獨的公共對象列表。
SEAF的都是不可取的,當你正打算爲對象構造函數如預期instanceof
將無法正常工作,以工作中的作用(參見:creating objects from JS closure: should i use the 「new」 keyword?)。
答:
- 如果是打算作爲一個Singleton /全球靜態實例,使用SEAF匿名函數。
如果您打算將其作爲
Constructor
(可能代表多個對象),或者您正在使用.prototype,請使用「標準」函數定義並使用「new」調用。:function PseudoClass1() {}
var PseudoClass2 = function() {};
var myClass1 = new PseudoClass1();
var myClass2 = new PseudoClass2();
我不得不說,我不是很滿意這個答案;)我發現.UsingNew模式更在代碼庫中是可讀的,但是由於事實上它比較慢,並且使用更多的內存然後SEAF未使用的原型參考被實例化並留在對象鏈中。
(晚來我知道黨..)很多人在這裏有趣的東西......因爲您更喜歡的UsingNew我不認爲單獨使用未使用的原型是足夠的理由來改變你的方法......這是一個非常小的內存量(爲了比較起見,它比使用模塊模式的編程人員不願意犧牲的數量要小得多原型。) – 2013-05-12 09:18:04
就匿名函數方法而言,如果您將返回變量「self」而不是「fnReturn」稱爲返回變量,則它可能看起來更具可讀性。您甚至可以將任何空對象傳遞給該函數,並將「self」作爲參數;然後從return語句和「self」而不是「this」的使用中獲益,函數的主體將與您的第一個示例相同。 – 2013-05-12 21:29:31
你應該[絕對不要使用'新功能]](http://stackoverflow.com/a/10406585/1048572) – Bergi 2015-01-26 02:11:14