for(var i = 0; i < 100; i++){
var foo = 5;
}
它有效......但这很糟糕吗?
我知道我可以var foo
在外面声明,但是当我只打算在循环中使用它时,为什么要这样做呢?
for(var i = 0; i < 100; i++){
var foo = 5;
}
它有效......但这很糟糕吗?
我知道我可以var foo
在外面声明,但是当我只打算在循环中使用它时,为什么要这样做呢?
随着时间的推移,我的个人风格已经发展成为一种偏好,即在我正在使用的特定语言的“头脑”中“实际存在”的地方声明变量。对于 JavaScript,这意味着将变量和函数声明放在语言会提升的位置反正他们。
这是为了清晰、精确的交流、理解、可维护性,让我自己的心理过程与语言的过程保持平行,仅举几个很好的理由。
因此,在这种特殊情况下,我不会将var foo = 5;
声明放入for
循环体中,原因很简单,因为它没有做看起来正在做的事情,也就是说,它实际上并没有重新声明/重新定义变量的范围每次迭代。(将var
声明放在 for 循环标头的初始化部分(初始化;条件;事后考虑)会更合理,当然也是将它放在确实具有块级变量的语言中的正确位置,例如当 JavaScript 完成采用let
- 块级范围的样式声明。)
笔记:
这种做法可能看起来不“正常”。我的大脑更喜欢让变量“接近”它们的使用,而我目前的实践并不是我的大脑工作方式自然而然的。但作为一名程序员,多年来,在混乱、沟通不畅、误解、无法解开的无法维护的代码等方面的经历,足以证明我需要遵循这种在与它们对应的位置声明变量的风格所需要的额外纪律。实际范围,与语言无关。
这种做法对我的一个额外好处是它鼓励我保持我的功能模块化和合理的大小。
同样,遵循这种做法会自动帮助我以合理的方式组织我的代码。例如,如果把我的函数放在首位会导致在我实际处理的代码之前有过多的函数,因此我对不得不读两页来编辑我的程序感到恼火,遵循这种风格会自动给我组织我的动力将代码转换为不同文件的适当结构。
PS One 可能会提出一个观点,即某些函数太长以至于这种做法使变量声明最终远离使用它们的页面。是的,我已经看到了正确的代码,甚至可能无法帮助的代码。然而,我不禁观察到散文作者和计算机程序员同样如此的相似之处。随着技能水平的提高,作者的句子长度(和程序员函数的大小)趋于增长,然后随着技能水平的不断提高,句子的长度(和程序员函数的大小)趋于缩短一次更多的。
这很糟糕,因为它给人一种错误的印象,即i
和foo
是局部变量。
for(var i = 0; i < 100; i++){
var foo = 5;
}
foo; // 5
这可能不是简单代码的问题,但是如果您使用闭包,很明显只有一个foo
:
var counters = [];
for (var i = 0; i < 100; i++) {
var foo = 5;
counters.push(function() { foo++; return foo; });
}
counters[0](); // 6
counters[0](); // 7
counters[1](); // 8 (!)
要foo
在不同的范围内创建一个函数,需要引入:
var counters = [];
for (var i = 0; i < 100; i++) {
(function() {
var foo = 5;
counters.push(function() { foo++; return foo; });
})();
}
counters[0](); // 6
counters[0](); // 7
counters[1](); // 6
这是一个由于这个原因而出错的真实示例:for-loop 中的 setTimeout 不会打印连续值
从 JavaScript 1.7 开始,您可以使用let
关键字(参见MDN)来创建真正的局部变量。