JavaScript 有很多遍历的方法, for,for in,for of(ES6),forEach,map,filter,every,some,jQuery 的 each 等等. 接下来通过一些例子来对比一下这些方法.
示例均使用如下测试数据:
- var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
1. for 循环
for 循环语句, 最基础的遍历, 以数组的下标为索引, 对数组元素进行遍历.
- function arrFor(arr) {
- try {
- var ret = '',
- st = performance.now();
- for (var k = 0; k <arr.length; k++) {
- ret += arr[k];
- }
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array for 总耗时:" + diff);
- } catch (e) {
- console.log("array for 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
array for 总耗时: 1.7999999690800905
2. for in
for in 循环不仅可以遍历数组, 还可以遍历对象, 但 for in 存在一些陷阱, 比如它会在遍历完元素之后, 还会对数组或对象的 prototype 中的属性进行遍历, 所以, for in 更像是为对象遍历而设计的.
示例:
- function arrForIn(arr) {
- try {
- var ret = '',
- st = performance.now();
- for (var k in arr) {
- ret += arr[k];
- }
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array for in 总耗时:" + diff);
- } catch (e) {
- console.log("array for in 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
array for in 总耗时: 1.5999999595806003
3. for of (ES6)
ES6 中引入了 for ... of 循环, 以替代 for...in 和 forEach() , 允许对 Array(数组),String(字符串),Maps(映射),Sets(集合) 等可迭代的数据结构进行遍历.
- function arrForOf(arr) {
- try {
- var ret = '',
- st = performance.now();
- for(var k of arr) {
- ret += k;
- }
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array for of 总耗时:" + diff);
- } catch (e) {
- console.log("array for of 报错了:" + e.message);
- }
- }
注意:
for(var k of arr) 中的 k , 就是数组 arr 中的元素, 而不是数组的下标.
IE 不支持, Edge 支持.
结果:
abcdefghijklmnopqrstuvwxyz
array for of 总耗时: 2.3999999975785613
4. forEach
forEach() 方法用于调用数组的每个元素, 并将元素传递给回调函数.
- function arrForEach(arr) {
- try {
- var ret = '',
- st = performance.now();
- arr.forEach(function (v, k) {
- ret += v;
- });
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array forEach 总耗时:" + diff);
- } catch (e) {
- console.log("array forEach 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
array forEach 总耗时: 1.7000000225380063
注意:
forEach() 对于空数组是不会执行回调函数的.
回调函数 function (v, k) 中的 k 是数组的下标, v 是数组元素值.
IE9 以下的版本不支持.
5. map
map() 方法返回一个新数组, 数组中的元素为原始数组元素调用函数处理后的值.
- function arrMap(arr) {
- try {
- var ret = '',
- st = performance.now();
- arr.map(function (v, k) {
- ret += v;
- });
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array map 总耗时:" + diff);
- } catch (e) {
- console.log("array map 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
array map 总耗时: 1.5999999595806003
6. filter
filter() 方法创建一个新的数组, 新数组中的元素是通过检查指定数组中符合条件的所有元素.
- function arrFilter(arr) {
- try {
- var ret = '',
- st = performance.now();
- arr.filter(function (v, k) {
- ret += v;
- });
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array filter 总耗时:" + diff);
- } catch (e) {
- console.log("array filter 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
array filter 总耗时: 1.6000000177882612
7. every
every() 方法用于检测数组所有元素是否都符合指定条件 (通过函数提供), 返回 boolen.
- function arrEvery(arr) {
- try {
- var st = performance.now();
- var ret = arr.every(function (v, k) {
- return v.length> 1;
- });
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array every 总耗时:" + diff);
- } catch (e) {
- console.log("array every 报错了:" + e.message);
- }
- }
结果:
false
array every 总耗时: 1.500000013038516
如果数组中检测到有一个元素不满足, 则整个表达式返回 false , 且剩余的元素不会再进行检测.
如果所有元素都满足条件, 则返回 true.
every() 不会对空数组进行检测.
every() 不会改变原始数组.
8. some
some() 方法用于检测数组中的元素是否满足指定条件 (函数提供). 只要有一个元素满足则返回 true, 并不再继续往下判断.
- function arrSome(arr) {
- try {
- var st = performance.now();
- var ret = arr.some(function (v, k) {
- return v.length> 1;
- });
- console.log(ret);
- var diff = performance.now() - st;
- console.log("array some 总耗时:" + diff);
- } catch (e) {
- console.log("array some 报错了:" + e.message);
- }
- }
结果:
false
array some 总耗时: 1.6999999643303454
如果有一个元素满足条件, 则表达式返回 true , 剩余的元素不会再执行检测.
如果没有满足条件的元素, 则返回 false.
some() 不会对空数组进行检测.
some() 不会改变原始数组.
9. jQuery 方法 $.each
each() 方法为每个匹配元素规定要运行的函数. jQuery 的 each 方法既可以遍历数组, 也可以遍历对象. 在遍历对象时可以很容易获取对象属性名.
- function jqueryEach(obj) {
- try {
- var ret = '',
- st = performance.now();
- $.each(obj, function(k, v) {
- ret += v;
- });
- console.log(ret);
- var diff = performance.now() - st;
- console.log("jquery each 总耗时:" + diff);
- } catch(e) {
- console.log("jquery each 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
jQuery each 总耗时: 2.8999999922234565
一般用法为:$(selector).each(function(index,element)) 或者 $.each(obj,function(index,element)) ; 回调函数中 index 参数是 对象 obj 的属性名 (或者 数组 obj 的索引),element 参数是 具体的值.
执行 return true 相当于 continue;
执行 return false 相当于 break;
10. Object.keys.forEach
Object.keys.forEach() 主要是用于遍历对象, 获取对象的属性名, 对于遍历数组意义不大.
- function objectKey(obj) {
- try
- {
- var ret = '',
- st = performance.now();
- Object.keys(obj).forEach(function(key, index, arr) {
- ret += obj[key];
- });
- //ES6 写法
- //Object.keys(obj).forEach(k => {
- // ret += obj[k];
- //});
- console.log(ret);
- let diff = performance.now() - st;
- console.log("object key 总耗时:" + diff);
- }
- catch (e)
- {
- console.log("object key 报错了:" + e.message);
- }
- }
结果:
abcdefghijklmnopqrstuvwxyz
object key 总耗时: 1.799999998183921
Object.keys.forEach 在遍历时, 回调函数的参数 key 是属性名 (对于数组, 属性名和索引一一对应),index 是 keys 数组的索引, arr 是 keys 数组; 所以在取值的时候还是用 obj[key]
来源: http://www.css88.com/qa/javascript/11522.html