4

for循环

这个是最常用,也是最简单的循环了。常用于数组或者类数组的遍历。
 for(let i=0;i<5;i++){
     console.log(`${i} is ${arr[i]}`);
 }

拓展:面试中经常爱考这样一道代码题:

    for(var i=0;i<5;i++){
        setTimeout(function(){
            console.log(i);
        },1000)
    }

问:最后分别打印出i的值是多少?

要注意,这里特意用了var声明,是因为let会有块级作用域,用let的话这段代码就很正常的打印出0,1,2,3了。

正常来说答案是5次5。
Ps:为什么说正常呢,我发现点CSDN的博客正文进去的控制台一直是打印5个1,我也不晓得为啥[/捂脸哭/]

这一道题就涉及了js的单线程和异步,闭包,作用域几个方面。

单线程的意思是同一时间不能分心,只能专心做一件事,而异步任务会先被插入到异步队列中,

只有当所有同步任务执行完毕后,栈被清空,才会读取任务队列里的任务并执行。

异步任务定时器,事件,回调函数等。
    
关于js线程这里有详细介绍:JS 演变、单线程、异步任务

说说作用域方面:其实上面的for循环等同于下面的写法:

var i=0;    
for(;i<5;i++){
    console.log(i)
}

由此可见,i是全局变量,所以在运行完后也没有销毁,而是一次次值被覆盖,直到最后一次。
因此,当执行定时器里面的函数时,同步任务已经执行完,但还是当拿到这个全局变量。

而这个问题有两个解决办法:作用域和闭包
作用域:把var改成let即可,因为let有块级作用域。
闭包:闭包的特性就是函数嵌套函数。

for(var i=0;i<5;i++){
    (function(i){
        setTimeout(function(){
            console.log(i);
        },1000)
    }(i))
}

每次for循环时都将i的值传入匿名函数,每次都创建了一个新的拥有私有变量i的匿名函数。

for in循环

它主要用来遍历对象,也可用来遍历数组。遍历对象时key是属性名,而遍历数组是字符串格式的下标值

缺点:它不能保证遍历顺序;不仅遍历自身属性,还会访问prototype上的属性。(可用hasOwnProperty加一层判断)
    let arr=['red','blue','green','grey'];
    for(let key in arr){
        console.log(`${key} is ${arr[key]}`);
    }

for of循环(ES6新增——遍历数组)

它可用来替代for in和forEach,它可以遍历 Arrays(数组/类数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代(Iterable data)的数据结构,注意它的兼容性。
与for in区别:

a.它的key值代表的是value值。
b.它不能单独遍历对象,因为获取不到对象的key值。
总的来说,对象用for in,数组用for of比较合适。

用法同for in就不重复了。

forEach循环(遍历数组)

它主要用来遍历数组,没有返回值
用法:arr.forEach(()=>(item,index,arr))

let arr=['red','blue','green','grey'];
arr.forEach(function(item,index,arr){
    console.log(`${index} is ${item}`);
    })

确实和ES6的map方法比较像。

map方法(ES6新增——遍历数组)

返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。我在React里用的话,经常是返回一个DOM结构。

let arr=['red','blue','green','grey'];
let result=arr.map((item,index,arr)=>{
        console.log(`${index} is ${item}`)
        return item;
    })

filter方法(数组内置方法)

看名字也知道是一个过滤功能,不过它不会改变原数组,只返回过滤后的元素,非常实用的一个方法,墙裂推荐。
参数和map一样。

   let arr=[3,53,43,65,32,5,52,64,2,64];
   let result=arr.filter((item)=>{return item%3=2;});

while 和 do while

讲真,while我用得很少,就是在算法里用过了。

while(条件为真){
    执行代码...
    循环条件变更
}
let n=1;
while(n<6){
    console.log('看进几次'); // 5次啦
    n++;
}

do while和while不同的是,它不管条件是否成立,反正都要走一次。
let n2=3;
do{
    console.log('至少走一次')            
    n++;
}while(n<3); // 这时候其实条件为假,但还是会进do的语句

平时工作就用到这些会比较多,日后有常用的再补充。


夕凪
258 声望11 粉丝