JavaScript数组和循环详解


Posted in Javascript onApril 27, 2015

数组是元素的一个有序组合。在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>
Javascript 相关文章推荐
setTimeout和setInterval的区别你真的了解吗?
Mar 31 Javascript
jquery插件制作 表单验证实现代码
Aug 17 Javascript
表单元素的submit()方法和onsubmit事件应用概述
Feb 01 Javascript
如何使用jquery控制CSS样式,并且取消Css样式(如背景色,有实例)
Jul 09 Javascript
JavaScript jQuery 中定义数组与操作及jquery数组操作
Dec 18 Javascript
jQuery页面刷新(局部、全部)问题分析
Jan 09 Javascript
微信小程序实现带刻度尺滑块功能
Mar 29 Javascript
Vue2单一事件管理组件通信
May 09 Javascript
Angular.js中angular-ui-router的简单实践
Jul 18 Javascript
详解vue渲染函数render的使用
Dec 12 Javascript
探秘vue-rx 2.0(推荐)
Sep 21 Javascript
如何用JS实现网页瀑布流布局
Apr 24 Javascript
javascript实现全局匹配并替换的方法
Apr 27 #Javascript
js限制文本框只能输入整数或者带小数点的数字
Apr 27 #Javascript
如何使用HTML5地理位置定位功能
Apr 27 #Javascript
jQuery插件scroll实现无缝滚动效果
Apr 27 #Javascript
Javascript非构造函数的继承
Apr 27 #Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
Apr 27 #Javascript
jquery简单的弹出层浮动层代码
Apr 27 #Javascript
You might like
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
php中Session的生成机制、回收机制和存储机制探究
2014/08/19 PHP
swoole和websocket简单聊天室开发
2017/11/18 PHP
Laravel timestamps 设置为unix时间戳的方法
2019/10/11 PHP
多个iframe自动调整大小的问题
2006/09/18 Javascript
一段效率很高的for循环语句使用方法
2007/08/13 Javascript
javascript firefox不显示本地预览图片问题的解决方法
2008/11/12 Javascript
纯文字版返回顶端的js代码
2013/08/01 Javascript
js查找某元素中的所有图片地址的方法
2014/01/16 Javascript
javascript实现避免页面按钮重复提交
2015/01/08 Javascript
JavaScript模拟重力状态下抛物运动的方法
2015/03/03 Javascript
jscript读写二进制文件的方法
2015/04/22 Javascript
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框
2015/12/12 Javascript
javascript实现倒计时跳转页面
2016/01/17 Javascript
非常实用的js验证框架实现源码 附原理方法
2016/06/08 Javascript
JS中对Cookie的操作详解
2016/08/05 Javascript
jQuery双向列表选择器DIV模拟版
2016/11/01 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
Vue.Js中的$watch()方法总结
2017/03/23 Javascript
使用js在layui中实现上传图片压缩
2019/06/18 Javascript
[02:10]三分钟回顾完美世界城市挑战赛
2019/01/24 DOTA
在Python中操作文件之seek()方法的使用教程
2015/05/24 Python
Python实现短网址ShortUrl的Hash运算实例讲解
2015/08/10 Python
python 文本单词提取和词频统计的实例
2018/12/22 Python
python输出电脑上所有的串口名的方法
2019/07/02 Python
python和c语言的主要区别总结
2019/07/07 Python
Python filter过滤器原理及实例应用
2020/08/18 Python
水污染治理专业毕业生推荐信
2013/11/14 职场文书
20年同学聚会邀请函
2014/02/04 职场文书
广告设计专业毕业生自我鉴定
2014/09/27 职场文书
2015年库房工作总结
2015/04/30 职场文书
2015年度学校卫生工作总结
2015/05/12 职场文书
2015年幼儿园德育工作总结
2015/05/25 职场文书
反邪教学习心得体会
2016/01/15 职场文书
win10键盘驱动怎么修复?Win10键盘驱动修复小技巧
2022/04/06 数码科技
Spring中的@Transactional的工作原理
2022/06/05 Java/Android