- for循环 只能循环数组
// 基础for循环
const arr = [11, 22, 33, 44, 55, 66, 77, 88];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 优化for循环 使用临时变量,将长度缓存起来,避免重复计算数组长度,当数组较大时优化效果才会比较明显
const arr = [11, 22, 33, 44, 55, 66, 77, 88];
for (let i = 0; len < arr.length; i < len; i++) {
console.log(arr[i]);
}
- forEach
- 对于forEach方法除非使用try/catch,否则无法中途停止循环,break或者return都无法使循环中途停止。而for…of循环可以与break,continue和return配合使用,中途停止循环;
- 数组自带的foreach循环,使用频率较高,实际上性能比普通for循环弱
const arrObj = [
{
id: 1,
name: "张三"
},
{
id: 2,
name: "李四"
},
{
id: 3,
name: "王五"
}
];
arrObj.forEach(item => {
console.log(item.id + "-------" + item.name);
});
- map
- map即是 “映射”的意思 ,原数组被“映射”成对应新数组
- map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
- map() 不会改变原始数组。
- map() 不会对空数组进行检测。
- map支持return
- 这种方式也是用的比较广泛的,虽然用起来比较优雅,但实际效率还比不上foreach
- filter遍历
- filter用于对数组进行过滤。
- filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
- filter() 不会对空数组进行检测;不会改变原始数组
- filter遍历
- filter用于对数组进行过滤。
- filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
- filter() 不会对空数组进行检测;不会改变原始数组
- for…of 方法
- 作为ES6新增的循环方法,个人觉得相当好用,而且方便。这个方法避开了for-in循环的所有缺陷。而且,它可以正确响应break、continue和return语句。
- 性能要好于forin,但仍然比不上普通for循环
- for in 既能循环数组,也能循环对象。
- 语句以任意顺序迭代一个对象的除 Symbol 以外的可枚举属性,包括继承的可枚举属性。
- 对构造函数的实例进行遍历时,会输出其原型上的可枚举属性。
- 如果只想输出是对象本身的使用 hasOwnProperty 即可.
- 在 for in 中可以使用 break 或者 continue 去中断循环,return 不能直接中断循环,必须放在函数中
- for in循环可以直接循环出Array的索引,但得到的是String而不是Number,所以一旦你想用这个index去进行计算,就会出错。
const obj = {
a: 'a',
b: 'b',
c: 'c',
[Symbol('a')]: '我是 symbol',
}
Object.defineProperty(obj, 'enumerableTrue', {
value: 'enumerableTrue',
enumerable: true
})
Object.defineProperty(obj, 'notEnumerableTrue', {
value: 'not-enumerableTrue',
enumerable: false
})
function TestProtoType () {
this.name = 'wfly'
}
TestProtoType.prototype = obj
const testProtoTypeObj = new TestProtoType();
for (let key in testProtoTypeObj) {
console.log('testProtoTypeObj.' + key + ' = 我是' + testProtoTypeObj[key])
}
console.log('=======');
for (let key in testProtoTypeObj) {
if (testProtoTypeObj.hasOwnProperty(key)) {
console.log('testProtoTypeObj.' + key + ' = 我是' + testProtoTypeObj[key])
}
}
console.log(testProtoTypeObj);
- Object.keys()、Object.entries()和Object.values()循环对象
- Object.keys()会返回一个表示给定对象的所有可枚举属性的字符串数组
let person={
name:'一只流浪的kk',
age:20,
eat:function(){}
}
console.log(Object.keys(person));// ['name','age','eat']
let arr=[1,2,3,4,5];
console.log(Object.keys(arr));//['0','1','2','3','4','5']
let str='hello';
console.log(Object.keys(str));//['0','1','2','3','4']
- Object.values()返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值
let obj = {
foo : "bar",
baz : 20
};
console.log(Object.values(obj)); // ["bar", 20]
- find
- 遍历数组,找到第一个符合条件的项,并返回该项;不会继续遍历数组;否则返回undefined
- 不会改变数组
- findIndex
- 遍历数组找到第一个符合条件的项,并返回该项的索引值;不会继续遍历数组;否则返回-1。
- 不会改变数组
- Array.some()
- 如果有一个元素满足条件,则表达式返回true,剩余的元素不会再执行检测。
- 如果没有满足条件的元素,则返回false。
- 返回值是布尔值
- Array.some()
- 如果数组中有一个元素不满足,则整个表达式返回false;且剩余的元素不会再进行检测
- 如果所有元素都满足条件,则返回true。
- 返回值是布尔值
- reduce() 方法
- 接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。
- 第二个参数作为第一次调用的a的值
上述列举了几种方式都有一一做过对比分析,基本上可以得出的结论是:
普通for循环才是最优雅的,优化后的for循环最快
注意:
数组方法无法中途停止循环,所以都不可以使用break和continue;
for循环之类的不可以return,但是能正常使用break和continue;