zoukankan      html  css  js  c++  java
  • JavaScript数组和循环

      数组是元素的一个有序组合。在JavaScript中,数组可以使用正式的对象表示法来创建,或者可以使用直接量表示法来初始化。

    var arrObject = new Array("val1", "val2"); // 作为对象的数组
    var arrLiteral = ["val1", "val2"]; // 数组直接量

      对于开发者来说,这没有区别:在直接量和对象上都可以调用一个Array方法。对于JavaScript引擎来说,每次访问数组直接量的时候,必须重新解释它,特别是在一个函数中使用它的时候。

      使用new运算符来创建一个新的Array对象:

    var arrObject = new Array();

      也可以创建带有某些值的一个新数组:

    var arrObject = new Array("val1", "val2");

      JavaScript中的数组是从0开始索引的,这意味着,第一个元素的索引是0,最后一个元素是数组的长度减去1。

    1、循环遍历数组

      问题:想要很容易地访问数组的所有元素。

      解决方案:

      要访问一个数组,最常用的方法是使用for循环:

    <script type="text/javascript">
        var animals = new Array("cat", "dog", "whale", "seal");
        var animalString = "";
        for (var i = 0; i < animals.length - 1; i++) {
            animalString += animals[i] + " ";
        }
        alert(animalString);
    </script>

      讨论:

      for循环可以用来访问数组的每一个元素。数组从0开始,而且数组属性length用来设定循环结束。

    2、按顺序存储和访问值

      问题:想要以这样一种方式来存储值,可以按照存储它们的方式来顺序访问值;

      解决方案:

      要按照接受值的顺序来存储和访问值,创建一个先进先出(FIFO)的队列。使用JavaScript Array对象的push方法,向队列添加项,并且用shift来获取项:

    <script type="text/javascript">
        // 创建新的数组
        var queue = new Array();
    
        // 压入3个条目
        queue.push("first");
        queue.push("second");
        queue.push("third");
    
        // 获取两个条目
        alert(queue.shift());
        alert(queue.shift());
        alert(queue);
    </script>

      讨论:

      Array push方法创建一个新的数组元素,并且将其添加到数组的末尾:

    queue.push("first");

      每次压入一个元素,数组元素的计数自增。

      Array shift方法从数组前面提取数组元素,将其从数组中删除,并且返回该元素:

    var elem = queue.shift();

      对于每一个shift操作的元素,数组元素会自减,因为shift除了返回该项,还会修改数组。

    3、以相反的顺序存储和访问值

      问题:想要以一种方式来存储值,即以相反的顺序访问值,先访问最近存储的值,也就是一个后进先出(LIFO)的栈。

      解决方案:

      要以相反的顺序存储值,创建一个LIFO栈。使用JavaScript Array对象的push方法来想栈添加项,使用pop方法来获取项:

    <script type="text/javascript">
        // 创建新的数组
        var stack = new Array();
    
        // 压入3个条目
        stack.push("first");
        stack.push("second");
        stack.push("third");
    
        // 弹出两个条目
        alert(stack.pop()); // 返回第三个条目
        alert(stack.pop()); // 返回第二个条目
        alert(stack); // 返回第一个条目
    </script>

      讨论:

      栈也是一个数组,其中每个新添加的元素位于栈的顶部,并且按照后进先出的顺序获取。

      Array push方法创建一个新的元素,并将其添加到数组的尾部:

    stack.push("first");

      每次压入元素的时候,数组元素的计数都会自增。

      Array pop方法从数组的尾部提取数组元素,将其从数组中移走,并返回元素:

    var elem = stack.pop();

      每次弹出一个元素的时候,数组元素计数会自减,因为弹出也修改了数组。

    4、在数组中搜索

      问题:想要在数组中搜索一个特定值,如果找到的话,获取该数组元素的索引。

      解决方案:

      使用新的(ECMAScript 5)Array对象方法indeOf和lastIndexOf:

    <script type="text/javascript">
        var animals = new Array("dog", "cat", "seal", "elephant", "lion");
        alert(animals.indexOf("elephant")); // 打印出 3
        alert(animals.indexOf("seal", 2)); // 打印出 2
    </script>

      尽管浏览器中有时候对indexOf和lastIndexOf都是支持的,但是,这只是ECMAScript 5的版本中正式化了。这两个方法都接受一个搜索值,然后,将其与数组中的每个元素比较。如果找到了该值,两个方法都返回该数组元素的一个索引。如果没有找到值,返回-1.indexOf返回找到的第一个元素,lastIndexOf返回找到的最后一个元素。

      参见:

      并非所有的浏览器都支持indexOf和lastindexOf,针对这一函数的解决方案:

    <script type="text/javascript">
        if (!Array.prototype.indexOf) {
            Array.prototype.indexOf = function (elt/*, from*/) {
                var len = this.length >>> 0;
                var from = Number(arguments[1]) || 0;
                from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    
                if (from < 0) {
                    from += len;
                }
    
                for (; from < len; from++) {
                    if (from in this && this[from] === elt) {
                        return from;
                    }
                }
    
                return -1;
            }
        }
    </script>

     5、对每个数字元素应用一个函数

      问题:想要使用一个函数来检查一个数组值,如果满足给定的条件,就替换它。

      解决方案:

      使用新的ECMAScript 5 Array对象的forEach方法,来针对每个数组元素都绑定一个回调函数:

    <script type="text/javascript">
        function replaceElement(element, index, array) {
            if (element == "ab") {
                array[index] = "**";
            }
        }
    
        var charSets = new Array("ab", "bb", "cd", "ab", "cc", "ab", "dd", "ab");
        //对每个数组元素应用函数
        charSets.forEach(replaceElement)
        alert(charSets); // 打印出**,bb,cd,**,cc,**,dd,**
    </script>

      讨论:

      forEach方法接受一个参数,这个参数是个函数。该函数自身有3个参数:数组元素,元素的索引和数组。

      参见:

      大多数浏览器都支持forEach。然而,对于那些不支持的浏览器,可以使用Array.prototype属性来模拟forEach行为。

    <script type="text/javascript">
        if (!Array.prototype.forEach) {
            Array.prototype.forEach = function (fun/*, thisp*/) {
                var len = this.length >>> 0;
                if (typeof fun != "function") {
                    throw new TypeError();
                }
    
                var thisp = arguments[1];
                for (var i = 0; i < len; i++) {
                    if (i in this) {
                        fun.call(thisp, this[i], i, this);
                    }
                }
            };
        }
    </script>

    6、创建一个过滤后的数组

      问题:想要过滤一个数组中的元素的值,并且把结果赋给一个新的数组。

      解决方案:

      使用Array对象的filter方法:

    <script type="text/javascript">
        function removeChars(element, index, array) {
            return element !== "**";
        }
        var charSets = new Array("**", "bb", "cd", "**", "cc", "**", "dd", "**");
        var newArray = charSets.filter(removeChars);
        alert(newArray); // bb,cd,cc,dd
    </script>

      讨论:

      filter方法是ECMAScript 5新添加的方法,该方法将一个回调函数应用于每一个数组元素。作为参数传递给filter方法的函数返回一个布尔值,true或false,根据测试数组元素的结果来返回。这个返回值决定了该数组元素是否添加到一个新的数组中,如果函数返回true,将会添加;否则,将不会添加。

      参见:

      对于不支持filter方法的浏览器的模拟实现:

    <script type="text/javascript">
        if (!Array.prototype.filter) {
            Array.prototype.filter = function (fun/*, thisp*/) {
                var len = this.length >>> 0;
                if (typeof fun != "function") {
                    throw new TypeError();
                }
    
                var res = new Array();
                var thisp = arguments[1];
                for (var i = 0; i < len; i++) {
                    if (i in this) {
                        var val = this[i]; // 放置fun修改了this
                        if (fun.call(thisp, val, i, this)) {
                            res.push(val);
                        }
                    }
                }
    
                return res;
            };
        }
    </script>

    7、验证数组内容

      问题:想要确保一个数组满足某个条件。

      解决方案:

      使用Array对象的every方法来检查给定条件的每个元素。

    <script type="text/javascript">
        function testValue(element, index, array) {
            var re = /^[a-zA-Z]+$/;
            return re.test(element);
        }
        var elemSet = new Array("**", 123, "abc", "-", "AAA");
        alert(elemSet.every(testValue));
    </script>

      讨论:

      Array对象的every和some方法都是最新的ECMAScript 5 Array方法,不同之处在于当使用every方法的时候,只要该函数返回一个false值,处理就会结束,并且该方法返回false。而some方法将继续测试每一个数组元素,知道回调函数返回true。此时不再验证其他的元素,该方法返回true。如果回调函数测试了所有的元素,并且任何时候不会返回true,some方法返回false。

      参见:

      对于不支持every和some的浏览器的实现方式:

    <script type="text/javascript">
        if (!Array.prototype.some) {
            Array.prototype.some = function (fun/*, thisp*/) {
                var i = 0,
                    len = this.length >>> 0;
                if (typeof fun != "function") {
                    throw new TypeError();
                }
    
                var thisp = arguments[1];
                for (; i < len; i++) {
                    if (i in this
                        && fun.call(thisp, val, i, this)) {
                        return true
                    }
                }
    
                return false;
            };
        }
    
        if (!Array.prototype.every) {
            Array.prototype.every = function (fun/*, thisp*/) {
                var len = this.length >>> 0;
                if (typeof fun != "function") {
                    throw new TypeError();
                }
    
                var thisp = arguments[1];
                for (var i=0; i < len; i++) {
                    if (i in this
                        && fun.call(thisp, val, i, this)) {
                        return false
                    }
                }
    
                return true;
            };
        }
    </script>
  • 相关阅读:
    线程池
    队列Queue、栈LifoQueue、优先级队列PriorityQueue
    线程的定时器Timer
    线程的条件Condiition
    线程的信号量Semaphore
    死锁的原因及解决办法RLock递归锁
    线程锁Lock
    守护线程daemon
    threding模块的其他用法
    变量的存储方式和生存期
  • 原文地址:https://www.cnblogs.com/libingql/p/3001548.html
Copyright © 2011-2022 走看看