网络编程
位置:首页>> 网络编程>> JavaScript>> 如何编写高质量的Javascript代码(4)

如何编写高质量的Javascript代码(4)

 来源:rockux 发布时间:2011-03-07 16:04:00 

标签:javascript,代码,经验

滥用了的var

JavaScript允许你在函数内部有多个var语句,但是却都表现的如同在函数的顶部声明一样。这个特性在你使用一个变量然后在后面又声明了这个变量时会导致一些奇怪的逻辑问题。对于JavaScript来说,只要变量在同一个作用域,那么就认为是声明了的,就算是在var语句之前使用也一样。看看这个例子:




myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

在这个例子中,或许你期望第一次会弹出global,第二次弹出local。因为第一次的时候没有还没有使用var声明myname,这是应该是全局变量的myname,第二次声明了,然后alert之后应该是local的值。而事实上不是这样的,只要你在函数中出现了var myname,那么js就认为你在这个函数中声明了这个变量,但是在读取这个变量的值的时候,因为var语句还没有执行,所以是undefined,很奇怪的逻辑吧。上面的代码相当于:




myname = "global"; // global variable
function func() {
   var myname; // same as -> var myname = undefined;
   alert(myname); // "undefined"
   myname = "local";
   alert(myname); // "local"
}
func();

我们来解释一下这个现象,在代码的解析中,分两个步骤,第一步先处理变量函数的声明,这一步处理整个代码的上下文。第二步就是代码的运行时,创建函数表达式以及未定义的变量。实际上,我们只是假设了这个概念,这并不在ECMAScript的规范中,但是这个行为常常就是这样解释的。

for循环

在for循环中你会去迭代一些数组元素或者一些HTML元素。for循环常常如此:




for (var i = 0; i < myarray.length; i++) {
   // do something with myarray[i]
}

这样写的问题在于,每一次迭代的时候都会计算数组的长度,尤其在这个参数不是一个数组而是一组HTML元素的时候会降低你的程序的性能。

HTML元素的集合在页面上,这样每次都会去再页面上查找相应的元素,这是非常耗时的。所以对于for循环,你需要预先保存数组的长度,这样写:




for (var i = 0, max = myarray.length; i < max; i++) {
   // do something with myarray[i]
}

这样缓存了参数的长度,在每次迭代的时候就不用再去查找计算了。

在查找HTML元素集合的时候,缓存参数长度可以带来可观的性能提升,Safari下面提高两倍的速度,在IE7下面提高190倍的速度。

需要注意的是,当你需要操作修改DOM元素的数量的时候,你肯定希望这个值是随时更新的而不是一个常量。

使用下面的单一var模式,你也可以把var提到循环之外:




function looper() {
   var i = 0,
        max,
        myarray = [];
   // ...
   for (i = 0, max = myarray.length; i < max; i++) {
      // do something with myarray[i]
   }
}

这个模式可以增强整个代码的连续性,但是不好的一点是当你重构代码的时候复制粘贴就没那么容易了。例如:如果你想在其他函数中也使用这个循环,那你需要确定在新的函数中处理好了i和max(或许还需要删掉这个)。

这个函数还有两个点可以优化的:

可以少一个变量(不需要max)

递减到0,一个数字与0比较比这个数字与另外一个数字比较更快
所以就可以写为:

var i, myarray = [];
for (i = myarray.length; i--;) {
   // do something with myarray[i]
}

针对第二点:

var myarray = [],
    i = myarray.length;
while (i--) {
   // do something with myarray[i]
}

这是两个比较微小的点的优化。另外,JSLint可能对于i–会有意见。

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com