深究js(七)——循环语句(语句Ⅱ)

来源:互联网 发布:js的某个div全屏显示 编辑:程序博客网 时间:2024/06/07 17:28

        前面第一部分初谈语句,接下来讲的是第二部分,也就是用的比较多的循环语句。在JavaScript中,有四种写法写循环语句,分别是:while、do/while、for和for/in,在es6中,还有一个新的循环,就是for/of,接下来我会细讲这五个循环还有他们之间的区别。

一、while循环

        一般来说,while循环的语法如下:

while (expression)    statement
        expression表示的是里面填的是表达式,statement表示的是执行的语句。while循环的执行顺序是先执行expression,当该表达式为真的时候,则执行while语句内的语句,然后再次计算expression里的值,一直循环下去。当为假的时候,则不执行这个while语句,执行它的下一行。当expression表达式里的值永远都是真值的时候,则会变成死循环,即一直执行while循环,不会执行while循环的下一行代码。


二、do/while循环

        do/while和while有点类似,只不过do/while是先执行statement,然后再进行expression表达式判断是否执行下一次循环。它的语句如下:

do     statementwhile (expression)
        这条循环最大的特点是循环至少会执行一次。而在while循环内是先进行判断,为真才执行循环。do/while语句的执行顺序是先执行do语句块,再执行while语句。同理,当while内的表达式一直为真,则是死循环。


三、for循环

        for语句比while语句更方便的控制循环的结构,for语句对常用的循环模式做了一些简化,它的语句如下;

for(initialize; test; increment)    statement
        其中initialize表示的是变量的初始化,test表示的是循环条件的判断,increment表示的是计数器变量的更新,计数器变量的更新不一定是递增,也不一定是递减,可以很灵活。statement表示的是循环内的语句。for循环执行的步骤是这样的,先执行initialize,对变量进行初始化,然后执行test,判断是否进入循环内,为真的时候则进入循环内,执行statement语句,执行完statement语句后再执行increment,之后执行test语句。反之如果一开始test语句里的表达式为假,则跳出for语句,执行for语句后面的代码。for循环它也可以用于遍历链表数据结构,下面代码就是一个例子,最后返回的是链表中最后一个对象:

function tail(o) {    for(; o.next; o = o.next);    return o}
        在这段代码中,我们可以看到,for语句内圆括号的内容不一定要全写,但是如果缺少了test表达式的话则会成为一个死循环。在for语句里,死循环还有这样的写法:

for(;;);


四、while、do/while、for三者之间的区别

        while与do/while的最大区别是while是先执行条件判断,然后视情况执行循环语句,而do/while则恰恰相反。那while与for循环有什么区别呢。明眼看的话,就是for语句小括号内有三个表达式而while只有一个。深入一点看的话,for在循环开始之前执行initialize表达式而while语句一开始就执行判断语句。如果更加深入的看的话,你会发现它们其实有更多的区别,虽然大多数情况下for语句可以改写成while语句,但是如果有了“continue”这个关键字,则情况不同。“continue”关键字不是这里的内容,这里简单介绍一下,continue是结束本次循环进行下一次循环。那我们来看看多了个continue关键字后这两个循环语句有什么不同。

        在JavaScript中,如果while语句内有continue语句,则运行到continue语句的时候,结束当前的逻辑,开始下一个循环,开始下一个循环的第一步是对expression表达式进行检测,真则运行下一个循环,假则跳出循环。而在for语句里,当执行到continue语句的时候,也是结束当前的逻辑,执行下一个循环,但是它的第一步是对increment表达式进行操作,让计数器的值先发生变化,然后在执行test表达式,检测是否为假,才会进行执行下一个循环。也就是说,从一个continue就可以看出这两个语句执行的步骤是不同的,所以在某些情况下这两个语句并非完全等价。


五、for/in循环

        for/in循环虽然也是用for这个关键字,但是它和for循环有很大的差别。首先我们来看看它的一般写法;

for (variable in object)    statement
        variable表示的是一个可以产生左值的表达式或者通过var语句声明的变量,通常用的是后者,object语句是一个表达式,这个表达式的结果是一个对象,通常直接写对象就可以了。如果object里填的不是一个对象而是一个原始值,比如填了一个数字5,则会将这个原始值转换成与之对应的包装对象,也就是说数字5转换的包装对象是Number("5")。如果object的结果是null或者underfined,则会跳出循环。

        for/in循环执行的步骤是先执行object表达式,如果是对象或者可以转换的对象,没有null或者underfined,则会依次枚举对象的属性来执行循环,然后到variable那里,先计算每variable,然后每个属性都会赋值给variable,之后再执行statement语句。下面有一个比较灵活的运用for/in表达式的代码,动态的给数组赋值:

var o = {x : 1, y : 2, z : 3}var a = [], i = 0for(a[i++] in o);
        a数组里的每个元素的值都是o对象各个属性的键名,但是for/in循环并不会遍历对象的所有属性,只有可枚举的属性才能够遍历到。比如toString()等内置的方法和内置对象的属性。能枚举出来的是在代码中定义的所有属性和方法还有对象继承其他对象的属性。关于枚举的顺序,现在一般按照先定义先枚举这个顺序来,如果有整数数组索引的属性,则按数字顺序来。


六、for/of循环

        for/of与上面的for/in类似,连写法也一样,但是for/in得到的是键名,而for/in得到的是键值。如:

var a = ['a', 'b', 'c']for(var b in a)    console.log(b)  //输出0,1,2for(var c of a)    console.log(c)  //输出a,b,c


七、for/in和for/of的区别

        for/in和for/of除了上面这个区别外,还有几个区别。一是for/of只能获取该对象的可枚举属性的值,而for/in能获取该对象及原型上可枚举属性的键名。如在MDN里有一个例子是这样的:

Object.prototype.objCustom = function () {};Array.prototype.arrCustom = function () {};let iterable = [3, 5, 7];iterable.foo = "hello";for (let i in iterable) {    console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"}for (let i of iterable) {    console.log(i); // logs 3, 5, 7}
        iterable这个数组对象是基于Object和Array这两个对象的,这个是一个原型链,在原型链上声明了两个属性,除此以外,还在该对象动态添加一个属性,这个时候for/in能获取所有可枚举的属性名而for/of只能枚举原本的属性的值,连动态添加的都不能获取到。

        除此以外,for/in是ECMAScript5的规范而for/of是ECMAScript6的规范,在使用for/of的时候,先要搞清楚当前浏览器是否支持ECMAScript6,才能够使用这个for/of。关于for/of及与for/in的区别,请参阅MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of



阅读全文
0 0
原创粉丝点击