JavaScript:事件处理程序:在哪里声明变量-本地或闭包(与开销相比)?
我发现自己正在编写各种包含事件处理程序的函数。最好在父函数(闭包)的根处声明处理函数所需的变量,特别是如果它们是jQuery选择、多个处理函数所需的常量,或者我不想在每次触发en事件时重复的一些预计算。一个简单的例子:JavaScript:事件处理程序:在哪里声明变量-本地或闭包(与开销相比)?,javascript,jquery,closures,jquery-events,Javascript,Jquery,Closures,Jquery Events,我发现自己正在编写各种包含事件处理程序的函数。最好在父函数(闭包)的根处声明处理函数所需的变量,特别是如果它们是jQuery选择、多个处理函数所需的常量,或者我不想在每次触发en事件时重复的一些预计算。一个简单的例子: var touchDrag = function() { var x, y, i; var $mySelection = $('.selection'); $('#some-elem').on( 'touchmove', function(e) {
var touchDrag = function() {
var x, y, i;
var $mySelection = $('.selection');
$('#some-elem').on( 'touchmove', function(e) {
x = something;
y = something;
i++;
$mySelection.doSomething();
// more code..
});
}
但是,我经常看到在处理函数(local)中声明处理变量。问几个编码员,一些争论接踵而至,但没有一个明确的答案
我理解,将变量范围保持在尽可能小的范围是一种很好的做法。但是,对于频繁触发的事件,如
.scroll()
或touchmove
,在我看来,每次触发事件时重新声明它们(而不是只分配一次每个变量)都会有很大的开销。通常,变量应该在需要的最小范围内定义。因此,如果一个变量只在touchmove
事件的实际处理过程中需要,并且它不会将状态从一个事件传递到下一个事件,那么我通常会在实际的touchmove事件处理程序中声明它,这样它的范围就尽可能小,并且在不使用时会被垃圾收集
当然,在更高的范围内声明它可能会有一些例外,例如:
另外,为了回应您的一个担忧,声明和初始化局部变量并不是一个“大开销”,除非计算初始值的工作是一项耗时的任务。但在您的示例中,当函数启动时,只需将
var x
移动到使用它的函数中,性能不会明显下降,事实上,它甚至可能在函数执行期间提高性能,因为访问局部变量比访问更大范围的变量更快(在检查更高范围之前,首先检查本地命名空间中的变量)
至于您现在添加到问题中的$mySelection
变量,我将在需要它的最小范围内声明它,直到/除非您有任何数据/信息表明它的初始化性能实际上给您带来了问题。一般来说,简单的选择器搜索操作非常快现代CPU
与几乎所有的性能问题一样,在没有任何证据表明某个性能问题实际上是一个问题之前,试图过早地解决该问题很少是一种有效的时间利用,也不是偏离最佳编码实践的理由。如果有疑问,请尽可能保持代码的简单和自包含性。尽管尽可能多地编写代码是一件好事,在某些情况下,重用变量可能会导致意外的问题
- 共享变量的更改可能会产生副作用。例如,在一些有大量事件的大型应用程序中,在其中使用共享变量可能会导致一些意外行为,因为事件是异步的,没有人能够预测事件何时完成
- (在我看来)很难读取和调试共享变量,因为我不知道是否有其他人在使用它(这会导致重构代码时出现一些问题)
$var
,直到/除非您有任何数据/信息表明其初始化性能实际上是正确的