由于JavaScript中的变量提升,无论是将
var
放在函数顶部还是放在
for
循环内部,在执行时都没有技术上的区别。如果这是你关心的全部内容,那么你可以选择任何一种方式。
仅为了刷新记忆,JavaScript提升意味着像您的第二个代码块这样的代码会被解析,然后就像您的第一个代码块一样执行。函数中的所有
var
声明都会自动移动到执行之前的函数范围的顶部。对这些变量的赋值在代码中的位置保持不变 - 只有变量的声明被移动。
因此,差异更多地取决于您想让代码看起来如何。当您将
var
定义放在
for
循环内部时,它使代码看起来像变量在每次迭代
for
循环时都被重新创建,尽管事实并非如此。它们每次循环迭代时被赋予一个值,但并不创建新变量。如果您使用
let
而不是
var
,那么情况就会不同,因为
let
具有块级作用域,而
var
只有函数作用域。
一般来说,最好将实际需要放在循环内部的代码放在循环内部。虽然将
var
放在循环内或外并不会实际更改执行中的任何内容,但它只是一个好习惯的一部分,而将其他代码放在循环内或外可能会有所不同。
在您的情况下,我认为这将是更好的做法:
function abc(){
var liTags = document.getElementsByTagName('LI');
var divTags = document.getElementsByTagName('DIV');
var len = Math.min(liTags.length, divTags.length);
var a,b;
for(var i = 0; i < len; i++){
a = liTags[i].width;
b = divTags[i].width;
}
return;
}
这里,你已经从循环中删除了两个调用 document.getElementsByTagName()
的代码,这将大大提高性能。
2017 年更新: JavaScript 版本 ES6 现在支持使用 const
和 let
声明变量。它们的作用域是块级作用域,而不像 var
那样是函数级作用域。所以如果你在 for
循环块内声明了其中一个变量,那么每次调用 for
循环都会创建一个新的独立变量。虽然这对于你展示的代码类型不会有任何显著的执行差异,但是在循环内部有引用所声明变量的异步代码时,就会产生不同。在循环体内使用 const
或 let
的情况下,每个异步调用都将获得其自己的变量副本,这有时非常方便。
for(var i = 0; i < len; i++){
let a = liTags[i].width;
let b = divTags[i].width;
$.get(someUrl).then(function(data) {
// each call to $.get() here in the loop has it's own a and b
// variables to use here, which would not be the case with var
});
}
for
语句中的变量在内,var
关键字会被提升。我认为,在函数顶部不声明它们(包括您不声明的那个)意味着 hoisting 不存在,并且只会让事情更难想,特别是未来的读者可能无法完全理解 JS。而且这只是噪音。 - Dave Newtonvar
关键字定义变量,它将被拉入全局范围 - 因此会创建与此问题无关的其他问题。 - dgo