死斗:自执行的匿名航班吗功能的“新功能”
答案在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未使用的原型参考被实例化并留在对象链中。
一方面,这种模式:
MyNamespace.UsingNew = new function() {
var fnPrivate = function() {
//what's this in here?
return "secrets1";
};
this.property = "value1";
this.method = function() {
//what's this in here?
return "property = " + this.property + ' ' + fnPrivate();
}
};
使用“新的”关键字来创建一个对象,这是使用一个构造函数建模的一个实例。忘记使用“新”,你最终会命名为功能
MyNamespace.UsingNew()
而不是一个对象。这是一个构造函数,而没有对象的实例(直到你建立了新的使用)。你需要使用“this”来表示它将成为的对象。它只是问题添加对范围,特别是当它在你嵌套更多的功能,以及价值“这一”将改变不时(你不会看到它的到来,直到控制台告诉的你)。熟悉
self=this
或that=this
保存的“本”的价值?它的otherhand使用这种模式
时几乎是看到,下一个模式是因为有所好转(对我来说):
你不需要用“新的”,因为它返回一个对象。
不使用“本”,因为它已经返回一个对象。你甚至不需要“这个”。
另外,我更喜欢建造另一模式是这样的:
ns.myobj = (function(){
//private
var _privateProp = '';
var _privateMeth = function(){};
//public
var publicProp = '';
var publicMeth = function(){};
//expose public
return {
prop:publicProp,
meth:publicMeth
};
}());
首先,谢谢你的一个很好的答案! – Campbeln 2012-03-20 22:14:50
原谅我的无知,但即使你忘记了“新”关键字并返回了一个函数而不是一个对象,有什么区别?我猜功能不是很多,但性能(很差)?至于你的前提。方法,你不觉得它是一个保姆。噩梦与底部的回报?我一直使用“.UsingNew”,请参阅:[link](http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/Renderer/Form/Form.js ),至于那个=这个问题,因为我在命名空间中构建,我只是完全解决了所需的功能。我觉得这比痛苦少一点痛苦。返回。 – Campbeln 2012-03-20 22:27:35
看看这个问题,我问如果何时使用“新”http://*.com/q/9304473/575527 – Joseph 2012-03-20 22:48:03
两个几乎是相同的,并应具有相对相同的性能特性。这只是一个风格问题。我个人赞成第二个,但它写得有点时髦。我会写它,
MyNamespace.UsingSelfEx = (function() {
function fnPrivate() {
return "secrets2";
}
return {
property: "value2";
method: function() {
return "property = " + this.property + " " + fnPrivate();
}
}
})();
你并不真的需要周围的功能,但自执行功能的括号通常有他们,让读者知道,一开始,这是一个自我执行的功能。
唉,你是对的!自我执行功能通常在他们周围有“额外”的角色!我很惊讶这似乎是做这个功能的首选方法。当我使用另一种方法时,我偶尔需要“this = that”方法,但是我发现FAR比以任何形式返回对象都要痛苦得多。另外,当我在命名空间中构建时,我通常只是引用我需要使用的this.function的完整名称空间地址。我确实倾向于将我的“私人”功能设计为“静态”,这无疑有助于.UsingNew方法。 – Campbeln 2012-03-20 22:36:52
请参阅:[链接](http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/Renderer/Form/Form.js)。哦,我还使用了“缩写”名称空间(在代码中用“Cn ._。*”表示)来帮助“rThis = Cn ._。short”作业(而不是“rThis = Cn.Some.Long .Namespace.Path“)。 – Campbeln 2012-03-20 22:37:27
由于这是形成一个名称空间,并且只有在这显然只是一种样式选择时才会执行。选择一个你喜欢的。我更喜欢上述,但那只是一个人的意见。 – chuckj 2012-03-21 00:17:34
我已经看到了这一点,我很喜欢它
var MyThing = (function(){
function MyThing(args){
}
MyThing.prototype = {
prototypeMethod: function() {}
};
return MyThing;
})();
你也可以做到这一点
MyThing.create = function(args){
return new MyThing(args);
}
它通常被封闭在一个又一个自我调用函数。 为了避免命名冲突。
(function({
})(window);
而window
对象被作为参数传递, 将其分配到的上范围。
window.MyThing = MyThing;
在这个例子中,你可以使用,静态变量,私营等
(晚来我知道党..)很多人在这里有趣的东西......因为您更喜欢的UsingNew我不认为单独使用未使用的原型是足够的理由来改变你的方法......这是一个非常小的内存量(为了比较起见,它比使用模块模式的编程人员不愿意牺牲的数量要小得多原型。) – 2013-05-12 09:18:04
就匿名函数方法而言,如果您将返回变量“self”而不是“fnReturn”称为返回变量,则它可能看起来更具可读性。您甚至可以将任何空对象传递给该函数,并将“self”作为参数;然后从return语句和“self”而不是“this”的使用中获益,函数的主体将与您的第一个示例相同。 – 2013-05-12 21:29:31
你应该[绝对不要使用'新功能]](http://*.com/a/10406585/1048572) – Bergi 2015-01-26 02:11:14