这些构造之间有什么区别,优点/缺点(如果有)?
new function(obj) {
console.log(obj);
}(extObj);
对比
(function(obj) {
console.log(obj);
})(extObj);
这些构造之间有什么区别,优点/缺点(如果有)?
new function(obj) {
console.log(obj);
}(extObj);
对比
(function(obj) {
console.log(obj);
})(extObj);
第一个返回对您的匿名构造函数 (= this
) 的新构造实例的引用。
第二个返回匿名函数的返回值。由于您的函数没有 return 语句,因此它将隐式返回 undefined。
尝试以下操作:
var t1 = new function(obj) { console.log(obj); }(extObj);
var t2 = (function(obj) { console.log(obj); })(extObj);
typeof t1 => "object"
typeof t2 => "undefined"
(顺便说一句,t1.constructor
将返回您创建的原始函数t1
。)
如果添加 return 语句,差异会变得更加明显:
var t1 = new function(obj){ return(obj); }("foo");
var t2 = (function(obj){ return(obj); })("bar");
console.log(t1) => "object"
console.log(t2) => "bar"
IMO,这(function)()
对于日常用例更加有用 - 您将执行此函数的返回值分配给变量,如果您正在使用立即调用的函数,这通常是您想要的。尤其是当有更复杂的东西时,比如(伪代码):
var myNameSpace = (function(){
/* do some private stuff here*/
...
/* expose parts of your anonymous function by returning them */
return{
functionX,
variable1,
variable2
}
}();
基本上,您可以使用任意一元运算符将函数声明转换为立即调用的表达式。所以你也可以写:
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
根据您的函数的返回语句,这些将给出不同的返回结果。!
- 否定返回值+|-
评估为数字(应用负号)~
应用于bitwise not
返回值。
如果您正在考虑明确处理立即调用的函数,那么两者之间没有任何真正的区别,除了第一个将this
在函数内部自动返回到外部世界(就是new
这样) ,并且默认情况下,如果未指定不同的返回值(常规函数返回undefined
)。
其余的主要区别并不重要——访问原型链将毫无意义,返回this.constructor
指向匿名函数的点将使您可以访问缓存匿名函数以供以后使用(例如从事件侦听器中删除它,如果您设法将封闭的函数粘贴在... ...这本身就是一个技巧)。
允许人们将您立即调用的函数缓存为返回this
对象的构造函数属性可能会带来安全风险... ...或者它可能真的很有用... ...在非常特定的场景中。
在线触发代码的日常目的——没有真正的区别。
另一个区别是第一次调用会创建一个额外的对象。在这里,我输入了名称f
并o
表示一个对象:
var o = new function f(obj) {
console.log(obj);
}(extObj);
在第二种情况下,我们仍然创建一个函数对象f
,但我们不创建o
:
(function f(obj) {
console.log(obj);
})(extObj);
仍然会创建一个闭包,但它比实际的 JavaScript 对象便宜,因为它不携带整个原型链或其他属性(如隐藏的类引用),