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 相关文章推荐
javascript 中对象的继承〔转贴〕
Jan 22 Javascript
javascript 去字符串空格终极版(支持utf8)
Nov 14 Javascript
js实现图片轮换效果代码
Apr 16 Javascript
jquery1.9 下检测浏览器类型和版本的方法
Dec 26 Javascript
在浏览器中实现图片粘贴的jQuery插件-- pasteimg使用指南
Dec 29 Javascript
js实现超酷的照片墙展示效果图附源码下载
Oct 08 Javascript
基于jQuery实现美观且实用的倒计时实例代码
Dec 30 Javascript
JS模拟简易滚动条效果代码(附demo源码)
Apr 05 Javascript
Angular1.x复杂指令实例详解
Mar 01 Javascript
vue-router二级导航切换路由及高亮显示的实现方法
Jul 10 Javascript
js遍历详解(forEach, map, for, for...in, for...of)
Aug 28 Javascript
QML实现圆环颜色选择器
Sep 25 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中FTP函数ftp_connect、ftp_login与ftp_chmod用法
2014/11/18 PHP
PHP页面跳转操作实例分析(header方法)
2016/09/28 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
Thinkphp5框架中引入Markdown编辑器操作示例
2020/06/03 PHP
jquery 页面全选框实践代码
2010/04/02 Javascript
js控制滚动条缓慢滚动到顶部实现代码
2013/03/20 Javascript
jquery插件validate验证的小例子
2013/05/08 Javascript
纯JavaScript实现获取onclick、onchange等事件的值
2014/12/29 Javascript
jQuery循环动画与获取组件尺寸的方法
2015/02/02 Javascript
jQuery简单实现验证邮箱格式
2015/07/15 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
JSP基于Bootstrap分页显示实例解析
2016/06/12 Javascript
js控件Kindeditor实现图片自动上传功能
2020/07/20 Javascript
每个程序员都需要学习 JavaScript 的7个理由小结
2016/09/03 Javascript
关于js原型的面试题讲解
2016/09/25 Javascript
vue裁切预览组件功能的实现步骤
2018/05/04 Javascript
Vue监听数据渲染DOM完以后执行某个函数详解
2018/09/11 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
2019/04/01 Javascript
vue响应式更新机制及不使用框架实现简单的数据双向绑定问题
2019/06/27 Javascript
vue实现图片预览组件封装与使用
2019/07/13 Javascript
如何实现一个简易版的vuex持久化工具
2019/09/11 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
vue之封装多个组件调用同一接口的案例
2020/08/11 Javascript
vue项目页面嵌入代码块vue-prism-editor的实现
2020/10/30 Javascript
python实现的简单抽奖系统实例
2015/05/22 Python
python网络编程之多线程同时接受和发送
2019/09/03 Python
如何关掉pycharm中的python console(图解)
2019/10/31 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
2020/06/18 Python
Elemental Herbology官网:英国美容品牌
2019/04/27 全球购物
物流管理专业大学生自荐信
2013/10/04 职场文书
个人自我鉴定怎么写
2013/10/28 职场文书
动物科学专业毕业生的自我评价
2013/11/29 职场文书
企划专员岗位职责
2013/12/09 职场文书
广告学专业求职信
2014/06/19 职场文书
2014年心理健康教育工作总结
2014/12/06 职场文书