• JavaScript基础Javascript中的循环(003)


    1.普通循环
    JavaScript中一般的循环写法是这样的:

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

     这种写法的问题是,每循环一次,都需要从myarray对象中读取length属性,这对于JavaScript来说,可能会导致较大的性能问题。如果myarray是一些大型的对象,或是DOM对象更犹是如此,因为DOM对象的这些方法都是在执行时才进行查询的。比如:
       document.getElementsByName()
       document.getElementsByClassName()
       document.getElementsByTagName()
    因此我们应该写成这样:

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

     这样我们就在循环一开始把max读取出来,以后就不再从myarray对象中查询了。当然,如果应用唯一var模式,我们应该把声明提高到函数的开头:

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

     这样做我们能得到唯一var模式的好处,但缺点是循环体代码不容易被复用。如果我们进一步缩短这段代码,可以改写成以下两种形式:

    var i, myarray = []; //精减后去掉max变量
    for (i = myarray.length; i--;) {
        // do something with myarray[i]
    }
    
    var myarray = [],
        i = myarray.length;
    while (i--) { //使用while循环
        // do something with myarray[i]
    }
    

     
    2. for-in循环
    for- in循环可以有效的遍历对象中的属性,但for-in一般不用在array对象中。一般来说,对于array对象,应该用普通的循环,因为for-in使用在array对象上的意义和遍历array中的元素并不一致。我们在对普通对象使用for-in时,要注意过滤掉对象中的方法,不然也会出现意想不到的问题。比如下面的代码使用Object.prototype,把clone方法加到了所有的对象中去:

    // the object
    var man = {
        hands: 2,
        legs: 2,
        heads: 1
    };
    
    // somewhere else in the code
    // a method was added to all objects
    if (typeof  Object.prototype.clone === "undefined") {
        Object.prototype.clone = function () {};
    }
    

     这时如果使用for-in循环,就必须使用hasOwnProperty()方法来过滤掉对象中的方法:

    // 1.
    // for-in loop
    for (var i in man) {
        if (man.hasOwnProperty(i)) { // filter
            console.log(i, ":", man[i]);
        }
    }
    /*
    result in the console
    hands : 2
    legs : 2
    heads : 1
    */
    

     如果不这么做,可能就会象下面的代码这样:

    // 2.
    // antipattern:
    // for-in loop without checking hasOwnProperty()
    for (var i in man) {
        console.log(i, ":", man[i]);
    }
    /*
    result in the console
    hands : 2
    legs : 2
    heads : 1
    clone: function()
    */
    

     hasOwnProperty()方法适用于所有的JavaScript对象,不过如果程序员手动的重定义了这个方法,上面的代码就不起效果了。这时就要使用下面的改进的写法:

    for (var i in man) {
        if (Object.prototype.hasOwnProperty.call(man, i)) { // filter
            console.log(i, ":", man[i]);
        }
    }
    

     这种改进的写法不用man来调用hasOwnproperty()方法,而是用Object的原型来调用。如果你觉得Object.prototype.hasOwnProperty太长,看起来有点啰嗦,也可以采用唯一var模式,把它定义在函数的前头:

    var i,
        hasOwn = Object.prototype.hasOwnProperty;
    for (i in man) {
        if (hasOwn.call(man, i)) { // filter
            console.log(i, ":", man[i]);
        }
    }
    

     在上面的例子中,我们使用对象原型(Object.prototype)来为所有的对象加入了方法,这种做法是十分便利的,但也可能会导致代码维护上的问题。因为其它的程序员不一定知道你对所有的对象都动了手脚。所以这种做法是不被鼓励的。如果你非要这样做,建议在此之前检查一下:

    if (typeof Object.protoype.myMethod !== "function") {
        Object.protoype.myMethod = function () {
            // implementation...
        };
    }
    
  • 相关阅读:
    417 Pacific Atlantic Water Flow 太平洋大西洋水流
    416 Partition Equal Subset Sum 分割相同子集和
    415 Add Strings 字符串相加
    414 Third Maximum Number 第三大的数
    413 Arithmetic Slices 等差数列划分
    412 Fizz Buzz
    410 Split Array Largest Sum 分割数组的最大值
    409 Longest Palindrome 最长回文串
    day22 collection 模块 (顺便对比queue也学习了一下队列)
    day21 计算器作业
  • 原文地址:https://www.cnblogs.com/Bryran/p/3969291.html
Copyright © 2020-2023  润新知