我有一个近乎强制性的习惯,但我认为这可能是完全没有必要的。使用如下代码:
function abc(){
var a,b;
for(var i=0;i<10;i++){
a=document.getElementsByTagName('LI').item(i).width;
b=document.getElementsByTagName('DIV').item(i).width;
// now do something with a and b
}
return;
}
我强制自己在循环之前声明变量,而不是:
function abc(){
for(var i=0;i<10;i++){
var a=document.getElementsByTagName('LI').item(i).width;
var b=document.getElementsByTagName('DIV').item(i).width;
// now do something with a and b
}
return;
}
请注意,在第二个代码块中,每次循环迭代时,我都使用 var 定义变量。我想第一个是可读性等方面的最佳实践。但有时我只是在破解一些东西,不需要遵循最佳实践。
我的问题是:
是否有任何理由不定义一个将在循环内使用var关键字重新定义的变量?
最佳答案
由于 Javascript 中的变量提升,在函数顶部或 for 循环内的 var 在执行上没有技术差异。如果这就是您所关心的,那么您可以采用任何一种方式。
只是为了刷新内存,Javascript 提升意味着像你的第二个代码块这样的代码被解析,然后像你的第一个代码块一样执行。函数内的所有 var 声明在执行前都会自动移动到函数作用域的顶部。对这些变量的赋值保留在它们在代码中的位置 - 只是移动了变量的声明。
因此,区别更多在于您希望代码的外观如何。当您将 var 定义放在 for 循环中时,它使代码看起来像是为 for 的每次迭代重新创建变量循环,即使事实并非如此。每次循环迭代都会为它们分配一个值,但不会创建新变量。如果您使用 let 而不是 var 就会出现这种情况,因为 let 具有 block 范围,而 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;
// now do something with a and b
}
return;
}
在这里,您已经从循环中删除了对 document.getElementsByTagName() 的两次调用,这将产生巨大的性能差异。
2017年更新 Javascript版本ES6,现在支持const和let声明变量。它们是 block 作用域的,而不是像 var 这样的函数作用域,因此如果您在 for 循环 block 中声明其中一个,那么将为每个创建一个新的独立变量调用 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
});
}
关于循环内的 Javascript 变量声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34952429/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。
我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty