Js数组遍历方法总汇

更新日期: 2019-06-30阅读: 1.9k标签: 遍历

for in

语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。主要用于枚举对象, 数组遍历效率最低的方法。

var ary = [1, 2, 3],
    obj = {
        name: 'Tom',
        age: 18
    },
    i;

for (i in ary) {
    console.log(i);
}

for (i in obj) {
    console.log(obj[i]);
}

注意:
1, 遍历数组时, i表示当前索引值,ary[i]对应的元素遍历对象时, i表示key值, obj[i]表示key值对应的value值;
2, 跳出循环的方式有如下几种:return 函数执行被终止, break 循环被终止, continue 循环被跳过;

缺点:
1, 遍历所有属性包括原型链;
2, 忽略 enumerable 为 false 的属性;

//构造函数
function Person() {
  this.name = 'mike';
};
//原型链属性
Person.prototype.age = 18;

//实例赋值
var mike = new Person,
  i;
mike.sex = 'man';
mike.height = '180';

//设置不可枚举
Object.defineProperty(mike, 'height', {
  enumerable: false
});

for (i in mike) {
  console.log(mike[i]);
}

优化方案:
hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象。不过需要注意的是, 此方法无法检查该对象的原型链中是否具有该属性, 该属性必须是对象本身的一个成员;

//构造函数
function Person() {
  this.name = 'mike';
};
//原型链属性
Person.prototype.age = 18;

//实例赋值
var mike = new Person,
  i;
mike.sex = 'man';

for (i in mike) {
  //过滤出对象自身的属性
  if (mike.hasOwnProperty(i)) {
    console.log(mike[i]);
  }
}       

注意: 这里依然会遍历所有属性,只是过滤出操作属性而已


For

循环可以将代码块执行指定的次数。

var ary = [1, 2, 3],
  i = 0,
  len = ary.length;

for (; i < len; i++) {
  console.log(ary[i]);
}

注意:
1, (如果使用var声明的话),for循环中的i在循环结束之后依然存在于作用域中, 为了避免影响作用域中的其他变量, 通常使用闭包或其他方式做处理
2, 避免使用for(var i=0, len = ary.length;i < len; i++){} 的方式, 数组长度每次循环都被计算, 效率低。将变量声明放在for的前面来执行
3, 跳出循环的方式有如下几种:return 函数执行被终止, break 循环被终止, continue 循环被跳过;

有种稍高逼格写法:

var ary = [1, 2, 3],
  i = ary.length - 1;

for (; i <= 0; i--) {
  console.log(ary[i]);
}

不考虑顺序情况下还不错,少一个变量并且能唬到一些新手


forEach(function(currentValue, index, arr), thisValue)

按照原始数组元素顺序依次处理元素.

参数描述
function(currentValue, index, arr)匿名函数,默认传参第1个是遍历的数组内容;第2个是对应的数组索引, 第3个是数组本身
thisValue可选。对象作为该执行回调时使用, 传递给函数, 用作 "this" 的值。如果省略了 thisValue , "this" 的值为 "undefined"

注意: forEach() 对于空数组是不会执行回调函数的。

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9];

ary.forEach(function (_ele, _index, _ary) {
  console.log(_ele, _index, _ary);
})

// 1 0 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 2 1 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 3 2 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 4 3 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 5 4 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 6 5 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 7 6 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 8 7 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 9 8 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

简单实现兼容写法:

Array.prototype._forEach = function (callback, context) {
  //指定指向, 默认window
  context = context || window;
  //浏览器支持直接调用方法, 终止后续操作
  if ('forEach' in Array.prototype) {
    this.forEach(callback, context);
    return;
  }
  //保证回调函数
  if (typeof callback !== 'function') throw 'callback must be a function'

  //遍历数组, 设置指向
  var i = 0,
    len = this.length;
  for (; i < len; i++) {
    callback.call(context, this[i], i, this)
  }
}

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9];
ary._forEach(function (_ele, _index, _ary) {
  console.log(_ele, _index, _ary);
})


map(function(currentValue,index,arr), thisValue)

按照原始数组元素顺序依次处理元素并返回一个新数组, 数组中的元素为原始数组元素调用函数处理后的值。

参数描述
function(currentValue, index, arr)匿名函数,默认传参第1个是遍历的数组内容;第2个是对应的数组索引, 第3个是数组本身
thisValue可选。对象作为该执行回调时使用, 传递给函数, 用作 "this" 的值。如果省略了 thisValue , "this" 的值为 "undefined"

注意: map() 对于空数组是不会执行回调函数的。

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var _ary = ary.map(function (_ele, _index, _ary) {
  console.log(_ele, _index, _ary);
  return _ele * 2
})
console.log('原数组: ' + ary);
console.log('返回数组: ' + _ary);

// 1 0 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 2 1 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 3 2 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 4 3 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 5 4 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 6 5 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 7 6 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 8 7 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 9 8 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 原数组: 1,2,3,4,5,6,7,8,9
// 返回数组: 2,4,6,8,10,12,14,16,18

简单实现兼容写法:

Array.prototype._map = function (callback, context) {
  //指定指向, 默认window
  context = context || window;
  //浏览器支持直接调用方法, 终止后续操作
  if ('map' in Array.prototype) {
    return this.map(callback, context);
  }
  //保证回调函数
  if (typeof callback !== 'function') throw 'callback must be a function'

  //遍历数组, 返回操作过的数组
  var _ary = [],
    i = 0,
    len = this.length;
  for (; i < len; i++) {
    _ary[i] = callback.call(context, this[i], i, this);
  }
  return _ary;
}

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9],
  _ary = ary._map(function (_ele, _index, _ary) {
    return _ele * 10
  });
console.log('原数组: ' + ary);
console.log('返回数组: ' + _ary); 


filter(function(currentValue,index,arr), thisValue)

使用指定的函数测试所有元素, 并创建一个包含所有通过测试的元素的新数组。

参数描述
function(currentValue, index, arr)匿名函数,默认传参第1个是遍历的数组内容;第2个是对应的数组索引, 第3个是数组本身
thisValue可选。对象作为该执行回调时使用, 传递给函数, 用作 "this" 的值。如果省略了 thisValue , "this" 的值为 "undefined"

注意: filter() 对于空数组是不会执行回调函数的。

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9],
  _ary = ary.filter(function (_ele, _index, _ary) {
    return _ele < 5
  });
console.log('原数组: ' + ary);
console.log('返回数组: ' + _ary);

// 原数组: 1,2,3,4,5,6,7,8,9
// 返回数组: 1,2,3,4

简单实现兼容写法:

Array.prototype._filter = function (callback, context) {
  //指定指向, 默认window
  context = context || window;
  //浏览器支持直接调用方法, 终止后续操作
  if ('filter' in Array.prototype) {
    return this.filter(callback, context);
  }
  //保证回调函数
  if (typeof callback !== 'function') throw 'callback must be a function'

  //遍历数组, 返回操作过的数组
  var _ary = [],
    i = 0,
    len = this.length;
  for (; i < len; i++) {
    if (callback.call(context, this[i], i, this)) {
      _ary.push(this[i])
    }
  }
  return _ary;
}

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9],
  _ary = ary._filter(function (_ele, _index, _ary) {
    return _ele & gt; 3
  });
console.log('原数组: ' + ary);
console.log('返回数组: ' + _ary);


every(function(currentValue,index,arr), thisValue)

用于检测数组所有元素是否都符合指定条件,返回布尔值.

参数描述
function(currentValue, index, arr)匿名函数,默认传参第1个是遍历的数组内容;第2个是对应的数组索引, 第3个是数组本身
thisValue可选。对象作为该执行回调时使用, 传递给函数, 用作 "this" 的值。如果省略了 thisValue , "this" 的值为 "undefined"

注意: every() 对于空数组是不会执行回调函数的。

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9],
  bol = ary.every(function (_ele, _index, _ary) {
    return _ele < 5
  });
console.log(bol); // false

简单实现兼容写法:

Array.prototype._every = function (callback, context) {
  //指定指向, 默认window
  context = context || window;
  //浏览器支持直接调用方法, 终止后续操作
  if ('every' in Array.prototype) {
    return this.every(callback, context);
  }
  //保证回调函数
  if (typeof callback !== 'function') throw 'callback must be a function'

  //遍历数组, 返回操作过的数组
  var _ary = [],
    i = 0,
    len = this.length;
  for (; i < len; i++) {
    if (callback.call(context, this[i], i, this)) {
      return false;
    }
  }
  return true;
}

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9],
  bol = ary._every(function (_ele, _index, _ary) {
    return _ele & gt; 5
  });
console.log(bol);


reduce/reduceRight(function(previousValue, currentValue, currentIndex, array), initialValue)

reduce对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果, 并且此返回值在下一次调用该回调函数时作为参数提供。
reduceRight反向操作.

参数描述
function(previousValue, currentValue, currentIndex, array)previousValue:通过上一次调用回调函数获得的值。如果向 reduce 方法提供 initialValue, 则在首次调用函数时, previousValue 为 initialValue。currentValue:当前数组元素的值。currentIndex:当前数组元素的数字索引。array:包含该元素的数组对象。
initialValue可选。传递给函数的初始值,

注意: reduce() 对于空数组是不会执行回调函数的。

先来打印看看里面的传参和没初始值的情况:

var ary = [1, 2, 3, 4],
  sum = ary.reduce(function (previousValue, currentValue, currentIndex, array) {
    console.log(previousValue, currentValue, currentIndex, array);
    return previousValue + currentValue
  });

console.log(sum);
// 1 2 1 [ 1, 2, 3, 4 ]
// 3 3 2 [ 1, 2, 3, 4 ]
// 6 4 3 [ 1, 2, 3, 4 ]
// 10
var ary = [1, 2, 3, 4],
  sum = ary.reduce(function (previousValue, currentValue, currentIndex, array) {
    console.log(previousValue, currentValue, currentIndex, array);
    return previousValue + currentValue
  }, 10);

console.log(sum);
// 10 1 0 [ 1, 2, 3, 4 ]
// 11 2 1 [ 1, 2, 3, 4 ]
// 13 3 2 [ 1, 2, 3, 4 ]
// 16 4 3 [ 1, 2, 3, 4 ]
// 20

两者区别在于多了一层运算,文档说明如下
在第一次调用回调函数时, 作为参数提供的值取决于 reduce 方法是否具有 initialValue 参数。
1, 有:

1) previousValue 参数为 initialValue。
2) currentValue 参数是数组中的第一个元素的值。

2, 没有:

1) previousValue 参数是数组中的第一个元素的值。
2) currentValue 参数是数组中的第二个元素的值。

简单实现兼容写法:

Array.prototype._reduce = function (callback, initValue) {
  //浏览器支持直接调用方法, 终止后续操作
  if ('reduce' in Array.prototype) {
    this.reduce(callback, context);
    return;
  }
  //保证回调函数
  if (typeof callback !== 'function') throw 'callback must be a function'

  //遍历数组, 设置指向
  var add = initValue || this.unshift(initValue),
    i = 0,
    len = this.length;
  for (; i < len; i++) {
    add = callback.call(null, add, this[i], i, this)
  }
}

var ary = [1, 2, 3, 4],
  sum = ary.reduce(function (previousValue, currentValue, currentIndex, array) {
    return previousValue + currentValue
  }, 20);
console.log(sum);


entries(), keys()和values()

它们都返回一个遍历器对象,可以用for...of循环进行遍历, 唯一的区别是keys()是对键名/索引值的遍历、values()是对键值的遍历, entries()是对键/索引值值对的遍历

var ary = [1, 2, 3, 4];
for (let elem of ary.keys()) {
  console.log(elem);
}
for (let elem of ary.values()) {
  console.log(elem);
}
for (let elem of ary.entries()) {
  console.log(elem);
}

写到这里就差不多了,ES5还有壹些筛选方法例如find(), includes()等其实都是大同小异就不继续写了,ES6还会涉及到叠代器的知识点,大家有兴趣自行研究吧.



链接: https://www.fly63.com/article/detial/4424

js中循环总结,多种循环遍历的实现介绍(while,for,map,foreach等)

循环是所有语言最基础的语法。这篇文章将介绍avascript多种循环遍历的实现介绍,包括for ..in遍历方式 ,do..while,forEach,for…of,map等等,

JavaScript数组遍历:for、foreach、for in、for of、$.each、$().each的区别

JavaScript数组遍历的区别,推荐在循环对象属性的时候使用for in,在遍历数组的时候的时候使用for of;for in循环出的是key,for of循环出的是value;for of是ES6新引入的特性。修复了ES5的for in的不足;

PHP遍历二叉树

遍历二叉树,这个相对比较复杂。二叉树的便利,主要有两种,一种是广度优先遍历,一种是深度优先遍历。什么是广度优先遍历?就是根节点进入,水平一行一行的便利。

js数组、对象、字符串的遍历

数组遍历:for --使用变量将数组长度缓存起来,在数组较长时性能优化效果明显,forEach --ES5语法;对象遍历:for...in --以任意顺序遍历一个对象自有的、继承的、可枚举的

Js二叉树与多叉树的遍历

二叉树的顺序存储结构就是用一维数组存储二叉树中的各个结点,并且结点的存储位置能体现结点之间的逻辑关系。二叉树的遍历有三种方式,如下:

JS中map与forEach的用法

相同点:都是循环遍历数组中的每一项;每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组)

深度优先遍历,广度优先遍历实现对象的深拷贝 深度优先遍历

深度优先遍历(Depth-First-Search),是搜索算法的一种,它沿着树的深度遍历树的节点,尽可能深地搜索树的分支。当节点v的所有边都已被探寻过,将回溯到发现节点v的那条边的起始节点。

Js中常见的几种循环遍历

项目开发中,不管是建立在哪个框架基础上,对数据的处理都是必须的,而处理数据离不开各种遍历循环。javascript中循环遍历有很多种方式,记录下几种常见的js循环遍历。

JavaScript中,数组和对象的遍历方法总结

循环遍历是写程序很频繁的操作,JavaScript 提供了很多方法来实现。这篇文章将分别总结数组和对象的遍历方法,新手可以通过本文串联起学过的知识。

javascript如何遍历对象?

javascript遍历对象的方法:1、使用Object.keys()遍历。2、使用for..in.遍历。3、使用Object.getOwnPropertyNames(obj)遍历。4、使用Reflect.ownKeys(obj)遍历。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!