1、for 循环
常用于循环数组、字符串,用于遍历对象,对象没有length属性,可用break或者throw跳出
  • demo:
let arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
    console.log(i, arr[i])
}
// 0 1
// 1 2
// 2 3

let str='demo'
for (let index = 0; index < str.length; index++){
    console.log(index,str[index]);
} 
// 0 'd'
// 1 'e'
// 2 'm'
// 3 '0'
2、for in循环
遍历一个对象的除Symbol以外的可枚举属性(得到可枚举属性也就是下标),可用break或者throw跳出
  • 语法:
for (variable in object) {
    // 在此执行代码
}
  • demo:
let obj = {
  name: '张三',
  sex: '男',
  age: 16
}
for(let item in obj) {
  console.log(item)
}
// 输出 name sex age

let arr = ['张三', '李四', '王五']
for(let item in arr) {
  console.log(item)
}
// 输出 0 1 2
3、for of循环
可迭代对象(obj{}不是,array[]是),区别得到是迭代的数据,可用break或者throw跳出
  • 语法:
for (variable of 可迭代对象) {
    // 操作语句
}
  • demo:
let arr = ['a', 'b', 'c']
let obj = {
  name: '张三',
  age: 18,
  sex: '男'
}

for (let i of arr) {
  console.log(i)
}
// 输出 a b c

for (let i of obj) {
  console.log(i)
}
// 报错 obj is not iterable (obj不是可迭代的)
4、switch循环
可迭代对象(obj{}不是,array[]是),区别得到是迭代的数据,可用break或者throw跳出
  • 语法:
switch (expression) {
    case x:        
        // execute case x code block
        //表达式
        break;    
    case y:
        // execute case y code block
        //表达式
        break;   
    default:  
         //表达式
         // execute default code block
  }
  • demo:
const grade = 87;
switch (true) {
    // If score is 90 or greater
    case grade >= 90:
        console.log("A");       
        break;    
     // If score is 80 or greater
    case grade >= 80:
        console.log("B");        
        break;    
     // If score is 70 or greater
    case grade >= 70:
        console.log("C");       
        break;    
      // If score is 60 or greater
    case grade >= 60:
        console.log("D");        
        break;    
      // Anything 59 or below is failing
    default:
        console.log("F");
}
5、while循环
switch 判断的是全等 === 而if 是相等==,对区间的判断用if,对几个固定的值判断用switch 能用if就用if
  • 语法:
while (variable) {
    console.log(variable + "<br>")
    variable++;
};
  • demo:
arr = ["1", "2", "3", "4"];
var i = 0;
while (arr[i]) {
    console.log(arr[i] + "<br>")
    i++;
};
// 防止死循环
while(true){
  console.log("我是死循环");
}
6、do while循环
先执行一次 因为循环体在前面 会先执行一次 再判断条件
  • 语法:
do {
    console.log(variable)
    variable--;
}
while (variable)
  • demo:
let i = 3;
do {
    console.log(i)
    i--;
}
while (i > 0)
// 3
// 2
// 1
7、forEach循环
没有返回值,三个参数(当前元素,当前元素的索引,当前正在调用的数组);forEach 循环在所有元素调用完毕之前是不能停止的,无法使用break等语句跳出遍历,但是可以使用抛出异常, 提前终止循环;只能用来遍历数组,不能用来遍历普通对象
  • 语法:
array.forEach((item,index,array) => {
   alert(e);
})
  • demo:
let arr = [1,2,3];
arr.forEach(function(i,index){
 console.log(i,index)
})
// 1 0
// 2 1
// 3 2

//异常用法
try {
    var arr = [1, 2, 3, 4];
    arr.forEach(function (item, index) {
        //跳出条件
        if (item === 3) {
          throw new Error("LoopTerminates");
        }
        //do something
        console.log(item);
    });
} catch (e) {
    console.log(e);    //打印出Error对象:Error: loopTerminates
    console.log(e.message); //打印:loopTerminates
};
8、map循环
参数同forEach,返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值,map()不会改变原始数组,只能用来遍历数组,不能用来遍历普通对象
  • 语法:
array.map(function(item,index,array){
    return i*2;
})
  • demo:
let arr = [1,2,3];
let newArr = arr.map(function(i){
    return i*2;
})
console.log(newArr)
// [2,4,6]
9、filter循环
参数同forEach,一个新的、由通过过滤条件元素组成的数组,如果没有任何元素通过,则[]
  • 语法:
array.filter(function(item,index,array){
    return i>1;
})
  • demo:
let arr = [1,2,3];
let newArr = arr.filter(function(i){
    return i>1;
})
console.log(newArr)
// [2,3]
10、some循环
参数同forEach,数组中是不是至少有一个元素通过条件,它返回的是一个Boolean类型的值,如果找到一个满足条件的元素, 则终止循环, 不在继续查找;如果用一个空数组,在任何情况下它返回的都是false,
  • 语法:
array.some(function(item,index,array){
    return i>1;
})
  • demo:
let arr = [1,2,3];
let booleanValue = arr.some(function(i){
    return i>1;
})
console.log(booleanValue)
//  true
11、every循环
参数同forEach,检测数组所有元素是否都符合指定条件,返回 boolean 值,不改变原数组。
  • 语法:
array.every(function(item,index,array){
    return i>1;
})
  • demo:
let arr = [1,2,3];
let booleanValue = arr.every(function(i){
    return i>1;
})
console.log(booleanValue)
// 检测数组中元素是否都大于1
//  false
12、reduce循环
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值;(场景:数组里所有值的和,累加数组中对象的值,将二维数组转为一维数组,计算数组中每个元素出现的次数,数组去重等);参数((total初始值,或者是上一次计算后的返回值,currentValue 当前元素, currentIndex 当前元素的下标, arr 当前元素所在的数组),initialValue) 归并基础的初始值)
  • 语法:
array.reduce((total, currentValue,currentIndex,array) => {
    return total + currentValue;
}, initialValue);
  • demo:
// 求和
let arr = [0,1,2,3];
let value = arr.reduce((pre, cur) => {
return pre + cur;
}, 0);
console.log(value);// 输出:6

//对象求和
let arr = [{ x: 1 }, { x: 2 }, { x: 3 }];
let value = arr.reduce((pre, cur) => {
return pre + cur.x;
}, 0);
console.log(value);// 输出:6

// 降维(二维数组转为一维)
let arr = [
    [0, 1],
    [2, 3],
    [4, 5],
];
let value = arr.reduce((pre, cur) => {
return pre.concat(cur);
}, []);
console.log(value); // 输出:[0, 1, 2, 3, 4, 5]

//计算数组中每个元素出现的次数
let arr = ["a", "b", "a", "c", "c", "c"];
let value = arr.reduce((pre, cur) => {
if (cur in pre) {
    pre[cur]++;
} else {
    pre[cur] = 1;
}
return pre;
}, {});
console.log(value); // 输出:{a: 2, b: 1, c: 3}

// 去重
let arr = [1, 2, 3, 2, 2, 3, 5, null, null, 0, false, false, true];
let value = arr.reduce((pre, cur) => {
return pre.includes(cur) ? pre : pre.concat(cur);
}, []);
console.log(value);//[1, 2, 3, 5, null, 0, false, true]
13、reduceRight循环
reduceRight()方法,和 reduce() 功能是一样的,它是从数组的末尾处向前开始计算。
  • 语法:
同reduce
  • demo:
同reduce
14、Object,keys(obj)
返回key组成的数组,则返回的是所有可枚举属性(不包括不可枚举属性(enumerable: true),原型属性,Symbol

),可遍历

  • 语法:
Object.keys(obj)
  • demo:
let obj = { a: 1, b: 2, c: 3, d: 4};
Object.keys(obj).map(key => { // ["a", "b", "c", "d"]
    console.log(obj[key]); // 1, 2, 3, 4
})
15、Object.getOwnPropertyNames(obj)
返回的是对象所有自己的属性(不包括Symbol,不包括原型)
  • 扩展:defineProperty(单个)和defineProperties(多个),用法: Object.defineProperty(对象,“属性名”,描述对象),描述对象中的属性及其各自的作用
  • 语法:
Object.getOwnPropertyNames(obj)
  • demo:
let obj = { a: 1, b: 2, c: 3, d: 4};
Object.getOwnPropertyNames(obj).map(key => { // ["a", "b", "c", "d"]
    console.log(obj[key]); // 1, 2, 3, 4
})

// 区别Object,keys(obj)
let obj = {}
Object.defineProperties(obj, {
    name: {enumerable: true, value: '卡卡西'},
    age: {enumerable: false, value: 25},
})
console.log(Object.keys(obj))
console.log(Object.getOwnPropertyNames(obj))
16、Object.entries(obj)
返回对象 obj 自身的可枚举属性的键值对数组(数组中的元素是一个由两个元素 key ,value 组成的数组)组成的二维数组,
  • 语法:
Object.entries(obj)
  • demo:
let obj = { a: 1, b: 2, c: 3, d: 4};
for (let [key, value] of Object.entries(obj)) { // [["a", 1], ["b", 2], ["c", 3],    ["d", 4]]
    console.log(key, value); // a 1 b 2 c 3 d 4
}
17、Object.getOwnPropertySymbols()
返回对象自身的 Symbol 属性组成的数组,不包括字符串属性
  • 语法:
Object.getOwnPropertySymbols(obj)
  • demo:
// 给对象添加一个不可枚举的 Symbol 属性
Object.defineProperties(obj, {
    [Symbol('baz')]: {
        value: 'Symbol baz',
        enumerable: false
    }
})

// 给对象添加一个可枚举的 Symbol 属性
obj[Symbol('foo')] = 'Symbol foo'
Object.getOwnPropertySymbols(obj).forEach((key) => {
    console.log(obj[key]) // Symbol baz, Symbol foo
})
18、Reflect.ownKeys(obj)
ES2015 新增的静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和 Symbol 属性,不包括原型(其实就是Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和)
  • 语法:
Reflect.ownKeys(obj)
  • demo:
Reflect.ownKeys(obj).forEach((key) => {
    console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo
})