我听说在函数顶部定义变量是一种很好的技巧,所以最终不会出现变量提升问题。这样:
// Beginning of file
function something(){
var a, b, c = 1, d, e;
// Do something
}
// End of file
是一个很好的例子(当然不包括错误的变量名称)。
我的问题是:这总是最好的方法吗?如果你正在使用很多变量怎么办?他们真的应该只是在一条线上吗?
答案 0 :(得分:47)
我强烈建议您阅读Code Complete 2 by Steve McConnell。他的论点是你既不应该在一行中声明所有变量 ,也不应该在例程的顶部声明它们。所以,不要这样做:
function foo() {
var a,
b,
c,
d;
/**
* 20 lines that use a and b
*/
/**
* 10 lines that use c and d
*/
}
相反,您应该将变量声明为接近需要的位置。在上面的代码中,可能如下所示:
function foo() {
var a,
b;
/**
* 20 lines that use a and b
*/
var c,
d;
/**
* 10 lines that use c and d
*/
}
这样做的好处是,只需查看上面的声明,您就可以快速了解一段代码所使用的变量。您不需要阅读代码来查看设置了哪些变量,只是声明了哪些变量。
不要为编译器或计算机编写代码。写给开发人员。您的代码应尽可能易于阅读,并且需要尽可能少的努力来理解特定的代码部分。
答案 1 :(得分:29)
我不这么认为。
以下是我将如何编写(忽略名称):
function something(){
var a,
b,
c = 1,
d,
e;
// Do something
}
这只在上面的中看起来很愚蠢,因为1)名称很糟糕2)变量未在“声明”中分配 - 大多数代码可以使用不可变(一次分配)变量编写我发现这可以简化代码。我使用它有多种原因,包括清晰度和对格式化更改的抵制(也就是说,我可以更改初始值,添加/删除声明等,而不会弄乱其他行的格式)。
我不这么认为。
例如,以下是我编写循环的方法:
for (var i = 0; i < x; i++) {
var elm = elms[i];
...
}
有些人会说“但是这些功能已经被提升到了最重要的位置!”或者“变量是功能性的!”。嗯,的确如此。但是,这使我能够轻松直观看到这是一个错误,即使JavaScript引擎无法帮助:
for (var i = 0; i < x; i++) {
var elm = elms[i];
...
}
...
// valid JS but since I consider this construct *invalid*
// I know this is a *bug* in my code
alert(elm);
当我分配到闭包中捕获的变量时:它取决于。如果变量仅在一个闭包中使用,我通常将它放在正上方。这让我知道只应该用在那个闭包中。如果变量是共享的(例如self
),我将它放在所有适用的闭包之上 - 通常在函数的“变量声明部分”中。这让我知道它有一个“功能范围”(读取:可能用于多个绑定)。
要解决“for-each-closure”问题 - 只需学习语言即可。保持变量“声明”接近闭包不会影响到这一点。如果不理解构造,那么如何编写代码并不重要。
我将这些方法用于/因为:
快乐的编码。
答案 2 :(得分:13)
在具有块范围的语言中,通常建议在首次使用的站点声明变量。
但是因为JavaScript没有块范围,所以在函数顶部声明所有函数的变量是明智的。这样你就不会欺骗自己或其他人关于变量的范围。
编辑:许多人同时使用多种语言。通常,JavaScript是其中唯一没有块范围的。
答案 3 :(得分:7)
这是一个风格问题。不是功能问题。
javascript解析器将采用此代码
function() {
dostuff();
var i = 4;
}
并将其转换为:
function() {
var i;
dostuff();
i = 4;
}
至于风格问题。不,谢谢,我以为我们用ANSI C留下了它。
您要做的是在“范围”
的顶部声明函数如果变量的“范围”是整个函数,则在顶部声明它们。如果“范围”是函数的子集,则在子集的开头声明它们。
将“范围”视为逻辑范围而不是功能范围。
这应该确保最大的可读性。
答案 4 :(得分:4)
我敢说,在较旧的结构中(例如C \ C ++天),初始化变量并为它们分配起始值非常重要。但随着事情的发展,我发现在“必要时”声明它们是一个有效的实现。除非范围正在发挥作用(例如,你不仅需要在该函数中使用变量a
,而且在其他函数中也需要变量{{1}},我会在移动中声明。
也许这只是思考方式,但我倾向于根据范围声明事物(如果仅在if条件或几行代码中需要变量,我会在那里声明它(而不是在顶部)我的函数/类)。如果我没有通过那个代码路径,我认为它保存了内存分配,并且它不会被“无理由”声明。)
然而,我可能完全错了。无论哪种方式,JavaScript都允许您以您认为最容易阅读的任何方式声明变量。答案 5 :(得分:4)
这实际上只是一个偏好问题。例如,如果我的方法只包含for循环,那么我不会将循环变量提取到顶部:
var func = function(arr) {
for (var i = 0, len = arr.length; i < len; i++) {
// array processing here
}
}
几乎所有其他时间虽然我会将所有变量放在顶部以提升原因。如果您发现函数顶部有太多变量,则可能表明您的方法做了太多工作,并且应该考虑将其中的一部分提取到某种辅助方法中。这样您就可以根据功能组织变量。