谈谈JavaScript的ECMA5中forEach

JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组首先想到的当然是for(var i=0;i<count;i++),在ECMA5中新增了forEach()方法。因为forEach()方法是ECMAscript5增加的方法,IE8以下(包括IE8)浏览器不完全支持ES5。写法简单了许多,但也有短处:你不能中断循环(使用语句或使用语句,这个之后实现中断或跳出循环)。语法:array1.forEach(callbackfn[, thisArg])

参数

定义

array1

一个数组对象。

callbackfn

对于数组中的每个元素,forEach 都会调用 callbackfn 函数一次。

thisArg

如果省略 thisArg,则 undefined 将用作 this 值。

异常:如果 callbackfn 参数不是函数对象,则将引发 TypeError 异常。1、1:原生写法

[].forEach(function(value, index, array) {
  // ...
});

例如:

var arr = [1,2,3,4];
arr.forEach(function(value,index,array){
  console.info("index:"+index+" value: "+value);  
});

结果输出为:

"index:0 value: 1"
"index:1 value: 2"
"index:2 value: 3"
"index:3 value: 4"

 

1、2:jQuery方式

$.each([], function(index, value, array) {
  // ...
});

1.3:map映射模式

[].map(function(value,index,array){
  //code
})

 

二、forEach()方法兼容与实现

2、1:因为forEach()方法是ECMAscript5增加的方法,IE8以下(包括IE8)浏览器不完全支持ES5,这里给出了一个IE兼容模式

if (!Array.prototype.forEach) {
     Array.prototype.forEach = function(callback, thisArg) {
        var T, k; 
        if (this == null) { 
            throw new TypeError("this is null or not defined"); 
        } 
        var O = Object(this); 
        var len = O.length >>> 0; // Hack to convert O.length to a UInt32 
        if ({}.toString.call(callback) != "[object Function]") { 
            throw new TypeError(callback + " is not a function"); 
        } 
        if (thisArg) { 
            T = thisArg; 
        } 
        k = 0;
        while (k < len) { 
            var kValue; 
            if (k in O) { 
                kValue = O[k]; 
                callback.call(T, kValue, k, O); 
            } 
            k++; 
        }  
     };
}

在IE8环境中贴出代码

var arr = [];
arr.push(1);
arr.push(2);
arr.push(3);
arr.push(4);
arr.forEach(function(value,index,array){
  alert("index:"+index+" value: "+value);  
});

输出结果:

"index:0 value: 1"
"index:1 value: 2"
"index:2 value: 3"
"index:3 value: 4"

 

三、如何中断forEach()方法

由于之前说到一个问题,如何在forEach里实现break,目前有几种方案

3、1:throw法抛出一个错误,但是需要注意的是要抛出一个可以与别的错误区别开的错误,这样不会干扰别的代码抛出的错误

var BreakException = {};
try {
    [1, 2, 3].forEach(function(v) {
        console.log(v); //只输出1,2
        if (v === 2) throw BreakException;
    });
} catch (e) {
    if (e !== BreakException) throw e;
}

//结果
1
2

 

3、2:空循环,在外层加一个标识,如果此标识为true,接下来的循环空跑

[1, 2, 3].forEach(function(v) {
    if (this.breakFlag === true) {
        return false;
    }
    if (v === 2) {
        this.breakFlag = true
    }
    console.log(v) //只输出1,2
});

 

3、3:修改数组

var array = [1, 2, 3, 4, 5];
array.forEach(function(item, index) {
    if (item === 2) {
        array = array.concat(array.splice(index, array.length - index));
    }
    console.log(item); //只输出1,2
});

 

 

3、4:使用的every:需要break的场景下,直接使用every或者some.every: 碰到return false的时候,循环中止some: 碰到return ture的时候,循环中止

var a = [1, 2, 3, 4, 5]
a.every(function(item, index, arry) {
    console.log(item); //返回1,2
    if (item === 2) {
        return false
    } else {
        return true
    }
});
var a = [1, 2, 3, 4, 5]
a.some(function(item, index, arry) {
    console.log(item); //返回1,2
    if (item === 2) {
        return true
    } else {
        return false
    }
})

四、总结

4、1:for-inJavaScript里还有一种循环方法:"对象而设计的,所以不推荐用for-in来循环一个数组,因为,不像对象,数组的index跟普通的对象属性不一样,是重要的数值序列指标。

var obj = {a:1, b:2, c:3};
for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}
// 输出:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

  

总之,for–in是用来循环带有字符串key的对象的方法。

4.2:参考  https://msdn.microsoft.com/zh-cn/library/ff679980(v=vs.94).aspx

22人参与, 0条评论 登录后显示评论回复

你需要登录后才能评论 登录/ 注册