假设我有以下功能:
function foo() {
}
function bar() {
}
Run Code Online (Sandbox Code Playgroud)
我可以在上面写为Object Literal表示法:
var Baz = {
foo: function() {
},
bar: function() {
}
};
Run Code Online (Sandbox Code Playgroud)
据我所知,在后一种情况下,无论是否调用任何Baz函数,脚本加载时都会创建一个Baz实例.在前一种情况下,仅在调用该函数时才创建函数对象.我对这些假设是否正确?
如果我是正确的那么前者将具有比后者在很少调用这些函数的应用程序中更高的性能(更少的内存).但后者的优势在于它提供了更大的模块化和更低的全局命名空间污染.
您从专业经验中对此有何看法?有速度差吗?
T.J*_*der 43
在前一种情况下,仅在调用该函数时才创建函数对象.
不,无论如何都会创建这些功能.
请注意,您也可以这样做:
function foo() {
}
function bar() {
}
var Baz = {
foo: foo,
bar: bar
};
Run Code Online (Sandbox Code Playgroud)
或这个:
var Baz = (function() {
function foo() {
}
function bar() {
}
return {
foo: foo,
bar: bar
};
})();
Run Code Online (Sandbox Code Playgroud)
将函数Baz作为属性放置的主要目的是使它们作为"方法"可用Baz.这可能是为了方便,"命名空间"等.在您的第一个表单(以及我上面的第一个表单)中,如果该代码处于全局范围,foo并且bar被添加到全局范围,这可能会非常快速地拥挤(特别是.在浏览器上).在第二个示例中,唯一的全局符号是Baz因为函数是匿名的.在上面的最后一个例子中,唯一的全局符号是Baz但函数不是匿名的,它们具有调试器和堆栈跟踪可以显示的名称(这是一件好事; 更多信息).
在尝试优化函数何时创建时,以下是它的工作原理:当执行进入给定的上下文(全局上下文或与调用函数相关的上下文)时,这些事情就完成了:
arguments(可用于访问参数的类似数组的事物)var在执行上下文中声明的每个变量,在变量对象上创建属性; 它们的值最初是undefined(无论是否var有初始化器).您将注意到函数声明和函数表达式之间的差异.您可以通过查看是否将结果用作右手值来判断哪个是哪个 - 也就是说,您是将结果分配给变量,将其用作对象中属性定义的右侧文字,或将其传递给函数.如果你是,那就是一个函数表达式.如果你不是,那就是一个功能声明.
函数声明示例:
function foo() {
}
Run Code Online (Sandbox Code Playgroud)
函数表达式示例:
var foo = function() {
};
Run Code Online (Sandbox Code Playgroud)
另一个:
var Baz = {
foo: function() { }
};
Run Code Online (Sandbox Code Playgroud)
(该foo行是对象文字中的属性声明,它使用函数表达式作为值.)
命名函数表达式示例:
var f = function foo() { // <== Don't do this (more below)
};
Run Code Online (Sandbox Code Playgroud)
命名函数表达式应该是有效的,但它们在野外(特别是IE)中的实现很难得到支持,因此现在必须避免它们.更多这里.