zoukankan      html  css  js  c++  java
  • ECMAScript5新增Array方法forEach的实现

    前言

    最近又开始变懒了,一个多星期没写blog了,负罪感油然而生。最近一直在看JavaScript高级程序设计一书,其中关于数组部分,ES5新增了5个迭代方法:every()、filter()、forEach()、map()、some()。每个方法都接收两个参数:要在每一项上运行的函数(可选的)运行该函数的作用域对象。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。大概用法的结构如下:

    // 这里是对于forEach的例子
    [1, 2, 3, 4].forEach(function(item, index, array) {
        // do something
    });

    虽然这些方法用起来很方便,但是遗憾的是浏览器的支持情况不太好,尤其对于IE系列版本,IE6-8都不支持,具体的浏览器支持情况如下:

    • Opera 11+
    • Firefox 3.6+
    • Safari 5+
    • Chrome 8+
    • Internet Explorer 9+

    forEach的使用

    ES5对forEach方法的描述是这样的:对数组中的每一项运行给定函数,并且该方法没有返回值,作用是对数组进行遍历、循环。

    如下例子所示:

    var numbers = [1, 2, 3, 4];
    numbers.forEach(function(item, index, array) {
        console.log(item + "\t" + index + "\t" + array);
    });

    firefox下结果:

    在Array原型上扩展forEach

    针对以上情况,为了使得ES5新增的数组迭代方法兼容主流浏览器(包括低版本),我们可以在Array原型上扩展这些方法,例如forEach方法: 

    // 特别是针对IE6、7、8
    if (typeof Array.prototype.forEach !== "function") {
        Array.prototype.forEach = function () {
            // 代码主体
        };
    }

    基于以上情况,我们可以对forEach进行扩展了,js代码:

    /**
     * 数组遍历
     * @param {Array|NodeList}
     * @param {Function}  遍历执行方法,执行方法中返回false值,则停止继续遍历
     * @param {Object} [scope] 执行方法的this指针
     */
     if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") {
         Array.prototype.forEach = function(callback, context) {
            // 遍历数组,在每一项上调用回调函数,这里使用原生方法验证数组。
            if (Object.prototype.toString.call(this) === "[object Array]") {
                var i,
                    len;
                for (i = 0, len = this.length; i < len; i++) {
                    if (typeof callback === "function"  && Object.prototype.hasOwnProperty.call(this, i)) {
                        if (callback.call(context, this[i], i, this) === false) {
                            break; // or return;
                        }
                    }
                }
            }
         };
     }

    使用时请注意参数的含义以及各参数的顺序

     demo1:不传入context作用域环境

    // 遍历数组
    [1, 2, 3, 4].forEach(function(value, index, array) {
        console.log(value, index, array);
    });

    firefox下结果(其他浏览器都已测试通过,这里只是提供FF下的结果截图):

    demo2:传入context作用域环境

    // 遍历数组,并在特定作用域中调用callback
    var data = {
        names: ["张三", "李四", "王五"],
        sayName: function(name) {
            if (/^王/.test(name)) {
                console.log("hello:" + name);
            } else {
                console.log("sorry:" + name + ",你不是本人!");
            }
        }
    };
    data.names.forEach(data.sayName, data);

    firefox下结果(其他浏览器都已测试通过,这里只是提供FF下的结果截图):

     

     到此forEach方法已经实现完毕,其他的迭代方法也是基于该forEach方法实现的,这里暂时不介绍,下次再补上。

    结语

     ╮(╯▽╰)╭,快十一点了,明天还要上课,今天就到此为止啦,吃夜宵去。

    因为分享,所以简单;因为分享,所以快乐。
  • 相关阅读:
    《Java练习题》Java习题集四
    《Java基础知识》Java 泛型详解
    《Java基础知识》Java正则表达式
    《Java基础知识》Java IO流详解
    《Java基础知识》Java集合(Map)
    51nod 1191:消灭兔子 贪心+优先队列
    51nod 1430:奇偶游戏 博弈
    51nod 1429:巧克力
    POJ 1423:Big Number 求N的阶乘的长度 斯特林公式
    51nod 1103:N的倍数 抽屉原理
  • 原文地址:https://www.cnblogs.com/cyStyle/p/forEach.html
Copyright © 2011-2022 走看看