处理循环variables的重复声明警告
考虑下面的代码:
for (var i=0; i<100; i++) { // your code here } // some other code here for (var i=0; i<500; i++) { // custom code here }
任何体面的lint工具(jslint,jshint或内置IDE)都会告诉警告 – duplicate declaration of variable i
。 这可以通过使用另一个名称( k
, j
)的variables或将声明移动到顶部来解决:
var i; // iterator for (i=0; i<100; i++) {} for (i=0; i<500; i++) {}
我不喜欢这两种变体 – 我不通常在顶部做声明(即使我做了也不想看到辅助variables – i
, j
, k
),在这些例子中真的没什么不好的改变variables的名字。
虽然我想要一个巨大的警告,如果我写这样的事情:
for (var i=0; i<100; i++) { for (var i=0; i<500; i++) {} // now that's bad }
你对这种情况有什么办法?
JavaScript有很多结构,看起来像其他计算机语言中的着名结构。 JavaScript以其他大多数计算机语言的方式来解释构造是危险的。
如果不认识JavaScript的人不够好(常见的情况就是这样)看结构
for (var i=0; i<100; i++) { // your code here }
或者在块中看到variables的声明
{ var i; //some code { var j; // some code } }
那么大多数读者会认为块级variables将被定义。 JavaScript没有块级variables。 所有variables将被解释为定义的function级别。
所以我从不在代码中定义variables,如果代码不只是一些testing代码,只会写5分钟。 主要原因是我不想编写代码,使用可能会被误解的语言结构 。
顺便说一句,JSLint发现块内部的variables定义了这样糟糕的风格,停止了代码分析的处理。 没有可以改变这种行为的JSLint选项。 我发现JSLint的行为不好,但是我同意在for
循环中声明variables是不好的,因为它会被大多数人读为带有本地循环variables的代码,这是不正确的。
如果你使用
for (var i=0; i<100; i++) { // your code here } // some other code here for (var i=0; i<500; i++) { // custom code here }
那么JavaScript会在函数的开头为你移动所有variables的声明。 所以代码将是
var i = undefined, i = undefined; // duplicate declaration which will be reduced // to one var i = undefined; for (i=0; i<100; i++) { // your code here } // some other code here for (i=0; i<500; i++) { // custom code here }
所以请考虑其他读者的代码。 不要使用任何可能被错误解释的结构。
let
关键字在JavaScript 1.7中引入。 请在这里findMDN文档
replacevar
let
inside for loop
解决了这个问题,现在可以在循环范围内声明局部variables。 在这里查看stackoverlow社区说明: 使用“let”和“var”声明一个variables有什么区别?
未来的代码:
for (let i = 0; i < someVar.length; i++) { // do your thing here }
我build议把你的循环放在自执行的函数中,这些函数的名字告诉你循环在做什么。 这有效地给块的范围循环。 例如:
var users = response['users'] ;(function appendUsers(){ for (var i = 0; i < users.length; i++) { var user = users[i] var userEmail = user['email'] var userId = user['id'] /* etc */ } })() // appendUsers
如果你这样做:
var i for (i = 0; i < someVar.length; i++) { for (i = 0; i < someOtherVar.length; i++) { // This is a bug that a validator will not notice. } }
另一方面:
for (var i = 0; i < someVar.length; i++) { for (var i = 0; i < someOtherVar.length; i++) { // This is a bug that a validator will warn you about. } } for (var i = 0; i < yetAnotherVar.length; i++) { // It will also warn you about this, but so what? }
你可以停止使用i
作为迭代器:
for (var companyIndex = 0; companyIndex < companies.length; companyIndex++) { var company = companies[companyIndex] }
如果你使用jQuery,你可以使用它的jQuery.each()
方法:
$.each(someVar, function(i, value){ // etc })
除非添加了Polyfill代码或类似的东西,否则你不能使用Array.prototype.forEach()
。
我倾向于使用数组内置的函数,比如map,filter和forEach,从而完全避免了这个问题。 这也自动给你的范围循环体也是非常有用的。
如果使用那些不符合用例的情况下,我通常会诉诸顶级声明,所以我可以避免你提到的问题。
这里的最佳实践应该是良好的编程风格:
一个程序应该用简短的function来构build,这将会起到一点作用。 通常情况下,如果你循环,你做一些特殊的事情应该站在自己的function。 最后每个函数都有自己的范围,这样重复声明问题就不存在了。
function myApp() { magicLoopAction(); someOtherMagicStuff(); } function magicLoopAction() { for (var i = 0; i < 42; i++) { // whoopwhoop } } function someOtherMagicStuff() { for (var i = 0; i < 69; i++) { // lint is happy and proud on you } }
- Google Chrome – JavaScript版本
- 什么时候应该使用删除vs设置元素在JavaScript中为null?
- 典型的AngularJS工作stream程和项目结构(使用Python Flask)
- HTML5canvasctx.fillText不会做换行符?
- 高级Javascript:为什么这个函数用圆括号包装?
- 怎样才能得到一个div标签的文本只使用javascript(没有jQuery)
- 使用Razor,我如何渲染布尔到JavaScriptvariables?
- node.js的unit testing框架,专门支持testingasynchronous代码?
- 你什么时候应该使用escape来代替encodeURI / encodeURIComponent?