在提出我的问题之前,让我给出免责声明.我知道什么var,我知道块范围,我知道变量提升.我不是在寻找有关这些主题的答案.
我只是想知道在函数中多次使用同一变量的变量声明是否存在功能,内存或性能成本.
这是一个例子:
function foo() {
var i = 0;
while (i++ < 10) {
var j = i * i;
}
}
Run Code Online (Sandbox Code Playgroud)
以前可以很容易地用j在顶部声明的variabled 编写:
function foo() {
var i = 0, j;
while (i++ < 10) {
j = i * i;
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道这两种方法之间是否存在任何实际差异.换句话说,var关键字除了建立范围之外还做了什么吗?
我听说过更喜欢第二种方法的原因:
我认为这些理由很好但主要是风格.还有其他原因与功能,内存分配,性能等有关吗?
在JavaScript - The Good Parts 中, Douglas Crockford 建议通过使用第二种方法并在其作用域的顶部声明变量,您将更容易避免作用域错误。
这些通常是由for循环引起的,并且很难追踪,因为不会引发错误。例如;
function() {
for ( var i = 0; i < 10; i++ ) {
// do something 10 times
for ( var i = 0; i < 5; i++ ) {
// do something 5 times
}
}
}
Run Code Online (Sandbox Code Playgroud)
当变量被提升时,我们最终只有一个i。因此第二个循环覆盖了该值,给我们一个无限循环。
在处理函数提升时,你也会得到一些奇怪的结果。拿这个例子:
(function() {
var condition = true;
if(condition) {
function f() { console.log('A'); };
} else {
function f() { console.log('B'); };
}
f(); // will print 'B'
})();
Run Code Online (Sandbox Code Playgroud)
这是因为函数体被提升,第二个函数覆盖第一个函数。
因为搜索这样的错误很难,而且不管任何性能问题(我很少关心几微秒),我总是在作用域的顶部声明我的变量。
执行期间不会有任何差异。解释/编译时间可能存在难以察觉的微小差异,但这当然取决于实现。文件大小也可能有几个字节不同,这也可能会影响下载时间。我认为这两件事都不值得担心。
正如您所知,任何变量声明都将被提升到函数的顶部。需要注意的重要一点是,这发生在解释/编译过程中,而不是执行过程中。
在执行函数之前,必须对函数进行解析。解析每个函数后,它们都将所有变量声明移至顶部,这意味着它们将是相同的,并且不会产生执行时间成本。
出于同样的原因,内存成本也没有差异。解析之后,就不会出现任何差异了。
既然你不是在问风格,我就不会告诉你我认为哪种更好。但我要说的是,您应该选择其中一种而不是另一种的唯一原因是风格。