在UPDATE 2/ANSWER中回答下面的内容
感谢Joseph帮助我找到答案(即使我不喜欢它=).
原始问题
虽然在JavaScript中使用Namepsaces时做的最佳做法的一些研究,我碰到这个定义中的"模型模式"的:http://yuiblog.com/blog/2007/06/12/module-pattern/.
自从我在YUI2年前看到它以来,我一直在使用这种模式,本文给出了概念的一个很好的概述.但它没有触及的是为什么"自我执行匿名函数"被用来代替"新函数".这在评论中被提出,但作者没有很好地描述.由于这篇文章已有4年多了(我在网上其他地方找不到答案),我想我会把它带到这里.
它已经关闭了,所以呢?(请参阅:为什么这个函数包含在括号中,后跟括号?它也没有回答我的问题=).
假设以下设置代码..
var MyNamespace = window.MyNamespace || {};
Run Code Online (Sandbox Code Playgroud)
哪个是首选,为什么?
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;
})();
Run Code Online (Sandbox Code Playgroud)
更新:
看起来像jQuery一样,所有酷孩子都在使用"自我执行匿名函数"(SEAF)!但我只是不明白这一点,因为我发现使用.UsingNew方法更清晰,因为你在定义中公开公共函数(而不是在需要单独维护或被迫使用内联对象的返回中)符号).
由于以下几个原因,不需要"那=这个"的论据并不适合我:
现在......我想我的开发风格可能会使.UsingNew模式更容易管理.我的"私人"功能本质上几乎总是"静态的",所以无论如何我都需要传递上下文(取代对"this"的需要).我也养成了使用"缩写"命名空间的习惯,所以当我确实需要访问"this"时,我只需通过"abbreviation"命名空间而不是通过它的完整路径来引用完整对象.例如:
var PrivateFunct = function() {
var rThis = Cn._.val; //# The abbreviated form of Cn.Renderer.Form.Validation
//...
};
Run Code Online (Sandbox Code Playgroud)
或者如果它是私有静态功能......
var PrivateStaticFunct = function(oContext) {
//...
};
Run Code Online (Sandbox Code Playgroud)
除了上面给出的原因,我个人发现.UsingNew方法在源代码中更具可读性.我有一个非常广泛的代码库,在这里使用.UsingNew模式:http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/,其验证功能可能是最简单的方法是快速阅读.我也使用了一些SEAF函数(参见ErrorMessages.js.aspx),但只有在它们有意义的时候.
我无法想象必须保持单独的返回以暴露底部的公共接口!呸!
现在,不要误会我的意思,有很多地方SEAF对于强制执行封闭非常有用,但我个人认为它在对象中过度使用.
更新2:
经过进一步反思(并且由于在他的回答下与约瑟夫进行了长时间的讨论),似乎有一些规则可以应用于这个死亡事件:
Per Douglas Crockford(参见:JS我们几乎没有新的Ya)匿名函数永远不应该使用"new"关键字,因为:
所以看来问题的关键是:SEAF var obj = new function() {...};比速度更快,开销更少(没有不需要的原型对象).你必须通过遭受什么是事实,你不得不使用对象的文字符号(因此,的而不是;"你的公有成员s之间),或在返回对象,以保持公共对象的单独列表.
SEAF的都是不可取的,当你正打算为对象的构造函数工作的功能instanceof将不会按预期工作(见:创建从JS关闭对象:我应该用"新"的关键字?).
回答:
如果您打算将其用作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();
}
};
Run Code Online (Sandbox Code Playgroud)
使用"new"关键字创建对象的实例,该实例使用构造函数建模.忘记使用"新",你最终会命名为一个函数MyNamespace.UsingNew()而不是一个对象.
它是一个构造函数,而不是一个对象的实例(直到你使用new构建它).你需要使用"this"来描述它将成为的对象.它只是向范围添加问题,特别是当你在其中嵌入更多函数时,"this"的值会不时改变(并且在控制台告诉你之前你不会看到它).熟悉self=this或that=this保存"这个"的价值?在使用这种模式时几乎可以看到它
另一方面,下一个模式对我来说有点好(因为我):
你不需要使用"new",因为它返回一个对象.
不使用"this",因为它已经返回一个对象.你甚至不需要"这个".
另外,我更喜欢用这种方式构建其他模式:
ns.myobj = (function(){
//private
var _privateProp = '';
var _privateMeth = function(){};
//public
var publicProp = '';
var publicMeth = function(){};
//expose public
return {
prop:publicProp,
meth:publicMeth
};
}());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5291 次 |
| 最近记录: |