Javascript JSlint:在函数范围内重新定义i
通过JSLint运行以下Javascript代码时:Javascript JSlint:在函数范围内重新定义i,javascript,jslint,Javascript,Jslint,通过JSLint运行以下Javascript代码时: (function () { var i = 'a'; console.log(i); function foo () { var i = 'b'; console.log(i); } foo(); console.log(i); foo(); }());
(function () {
var i = 'a';
console.log(i);
function foo () {
var i = 'b';
console.log(i);
}
foo();
console.log(i);
foo();
}());
我在JSLint中得到以下错误:
#1 Redefinition of 'i' from line 4.
var i = 'b'; // Line 7, Pos 13
#2 Unused 'i'.
var i = 'a'; // Line 4, Pos 9
#3 Unused 'foo'.
function foo () { // Line 6, Pos 14
我的问题是:
var i='b'
的函数是它上面的函数的重新定义var i='a'
定义未使用您将得到
i
的重新定义,因为它存在于两个作用域中
这本身并不是一个真正的问题,但是Crockford认为这是一件会引起混淆的事情,所以他的工具会捕捉到它。首先,如果在jslint.com上运行代码,您只会得到重新定义错误,这是有效的。所以我不确定你为什么会看到错误1和3。你还好吗?它是否在另一个应用程序中?您使用的jslint.js的日期是什么?等等
/*jslint sloppy:true, white:true, browser:true, devel:true */
(function () {
var i = 'a';
console.log(i);
function foo () {
var i = 'b';
console.log(i);
}
foo();
console.log(i);
foo();
}());
那只给了我
Redefinition of 'i' from line 3.
var i = 'b';
很公平。在你的问题的评论中,帕斯蒂也做了同样的交易。正如杰里米所说,密码不会被破解。只是让人困惑。为什么不在foo
中使用j
(当然,也可以在live code中使用描述性变量名),或者在pastie的中使用匿名函数
当您使用JSLint时,请务必记住,“当使用难以区分明显错误的习惯用法时,编写正确的程序是很困难的。”用foo
的内部i
覆盖您的外部i
是令人困惑的
想象一下如果foo
read
function foo () {
console.log("Maybe I think I'm getting old 'i' here: " + i);
var i = 'b';
console.log(i);
}
JSLint(奇怪的是,如果你问我的话)并不要求var
语句是每个作用域的第一行,只要求它发生在引用变量之前
因此,如果您使用新的foo
运行测试代码,那么在到达变量的声明语句b/c之前,foo
的i
将被取消定义。奇怪吧?(或预期,取决于您的JS体验!)
你可能会说JSLint错了——它不仅应该抱怨的重新定义,还应该抱怨'i'在定义之前就被使用了。
在foo
的范围内。我不会争辩的
然而,我要说的是,重新定义是一个很难与明显错误区分开来的习语。最佳实践?不要对重叠作用域中的不同值重复使用变量名。先声明函数,然后再声明var
,这样声明的顺序就正确了,JSLint就不会报告任何错误。@Teemu:也许更好的例子是将闭包用作回调。如果在该闭包中定义var i
,JSLint会报告相同的错误,这都与提升有关。函数和变量声明被提升到其作用域的顶部,函数应该是第一个,然后是变量。如果它们的顺序不正确,JSLint会报告一个错误,显然无法正确处理其余的代码,至少从人的角度来看,“未使用的变量”感觉不合逻辑。好吧,也许是一个更好的问题——为什么我在这里得到“我”的重新定义:很难说,也许你必须问Crockford先生;)。谢谢,很好地解释了它背后的原因。
a
Maybe I think I'm getting old 'i' here: undefined
b
a
Maybe I think I'm getting old 'i' here: undefined
b