javascript中有两种流行的闭包样式。第一个我叫匿名构造函数:
new function() {
var code...
}
和内联执行功能:
(function() {
var code...
})();
这两者之间的行为有何不同?一个人比其他人“更好”吗?
答案 0 :(得分:9)
两种情况都会执行该函数,唯一真正的区别是表达式的返回值可能是什么,以及“this”的值将在函数内部。
的基本行为
new expression
实际上相当于
var tempObject = {};
var result = expression.call(tempObject);
if (result is not an object)
result = tempObject;
虽然tempObject和result当然是瞬态值,但你永远看不到它们(它们是解释器中的实现细节),并且没有JS机制来执行“不是对象”检查。
一般来说,由于需要为构造函数创建此对象,因此“new function(){..}”方法将会变慢。
那说这应该不是真正的区别,因为对象分配不是很慢,你不应该在热代码中使用这样的代码(由于创建函数对象和相关闭包的成本)。
编辑:有一件事我意识到我错过了tempObject
会获得expression
的原型,例如。 (在expression.call
之前)tempObject.__proto__ = expression.prototype
答案 1 :(得分:5)
@Lance:第一个也在执行。将它与命名构造函数进行比较:
function Blah() {
alert('blah');
}
new Bla();
这实际上也在执行代码。匿名构造函数也是如此......
但那不是问题; - )
答案 2 :(得分:3)
它们都通过执行代码块来创建闭包。作为一种风格问题,我更喜欢第二种,原因如下:
首先看一下代码实际执行情况并不是很明显; 行似乎 创建一个新函数,而不是将其作为构造函数执行,但这不是实际发生的事情。避免代码不能正常运行!
此外(function(){
... })();
制作了很好的书挡标记,以便您可以立即看到您正在进入和离开关闭范围。这很好,因为它会提醒程序员将其读取到范围更改,并且如果您正在对文件进行一些后处理(例如缩小),则会特别有用。
答案 3 :(得分:0)
第二个例子将在创建后执行该功能。
编辑:这不是真的。
答案 4 :(得分:0)
好吧,我做了这样一个页面:
<html>
<body>
<script type="text/javascript">
var a = new function() {
alert("method 1");
return "test";
};
var b = (function() {
alert("method 2");
return "test";
})();
alert(a); //a is a function
alert(b); //b is a string containing "test"
</script>
</body>
</html>
令人惊讶的是(无论如何)它提醒“方法1”和方法2“。我没想到”方法1“被警告。不同之处在于a和b的值是什么.a是函数本身,而b是函数返回的字符串。
答案 5 :(得分:-4)
是的,两者之间存在差异。
两者都是匿名函数,并以完全相同的方式执行。但是,两者之间的区别在于,在第二种情况下,变量的范围仅限于匿名函数本身。没有可能意外地将变量添加到全局范围。
这意味着通过使用第二种方法,您不会弄乱全局变量范围,因为这些全局变量值可能会干扰您可能在某些其他库中使用或正在某些其他库中使用的其他全局变量。第三方图书馆。
示例:
<html>
<body>
<script type="text/javascript">
new function() {
a = "Hello";
alert(a + " Inside Function");
};
alert(a + " Outside Function");
(function() {
var b = "World";
alert(b + " Inside Function");
})();
alert(b + " Outside Function");
</script>
</body>
</html>
在上面的代码中,输出类似于:
Hello Inside Function
你好外面的功能
世界内幕功能
...然后,你得到一个错误,因为'b'没有在函数外定义!
因此,我相信第二种方法更好......更安全!