JavaScript控制语句见习

1.标签跳转

类似于C语言里面有goto语句,JavaScript里面有个语句跳转的玩意儿,叫做标签跳转。不过它没有C语言这么夸张,C语言好像设定是可以跳转到函数内任意的地方。我们先来看一个C语言的例子。

#include <stdio.h>

int main() {
  int i = 0;
 tag:
  printf("Hello Lan\n");
  printf("Hello World\n");
  if(i < 10) {printf("%d\n", i);}
  goto tag;
}

很遗憾这里是一个无限循环。会不断打印出Hello Lan, Hello World, 0。在taggoto之间还是可以存在有挺多语句的。这样给C语言带来了不少麻烦。所以就算是C语言的作者也不建议我们使用goto语句。如果太多这类跳转只会徒增代码维护的成本。(更可怕的是Review你代码的人可能会拿着菜刀来追你!!)

于此相对应的Javascript的跳转有节操很多。标签只定义在条件语句或者循环语句前面, 而且如果标签与目标语句之间还有额外的语句,就不能通过解释器。我们只能从条件语句或者循环语句内部通过continue, break两个关键字进行跳转。。不再多说,举几个栗子就很好理解了。

// example.js
var a = 10;
tag1:while(a < 100) {
    a++;
    if (a == 90) continue tag1;
}
console.log("value of a is: " + a);

var b = 10;
tag2: if(b < 100) {
    b++;
    break tag2;
}
console.log("value of b is: " + b);

var c = 10;
tag3:while(c < 100) {
    c++;
    if (c == 90) break tag3;
}
console.log("value of c is: " + c);

打印的结果是:

value of a is: 100
value of b is: 11
value of c is: 90

continue跳转tag会跳转到tag的位置,然后继续执行对应的循环。(因为条件语句里面也用不了continue),而break跳转tag会终止tag所指示的循环语句或者条件语句的运行。

这里我们tag1用了continue所以它会跳转到tag1然后继续执行while循环,直到a>=100才退出循环。而我们tag2处用了break,直接结束了tag2所指示的语句。我们只执行了一次b++所以得到了11这个结果。

不能够在标签与指定语句之间添加其他语句,或者在条件以及循环以外的情景打标签。下面是错误示范

// error1.js

var d = 10;
tag4:
// 在标签与想指定的循环之间插入语句。
console.log("good");
while(d < 100) {
    d++;
    if (d == 90) break tag3;
}
console.log("value of d is: " + d);
// error2.js
// 对函数打标签, 这条也是错误的语法
tag:function errorFun() {
    console.log("good");
    break tag;
}

上面的语句都是无法通过解释器的。只是作为反面教材。请大家谨慎了。总的来说Javascript的跳转相比于C可维护性方面还是稍微高了点。毕竟限制多了。大家酌情使用吧。

2.continue语句对于for跟while两种循环会有不同的行为

continue语句在while循环中直接进入下一轮循环。而在for循环中使用则先计算increment表达式,然后再进行循环条件判断。

-_-这听起来就是个坑嘛。

我还是举例子说明一下

// loop1.js
for (var i = 0; i < 10; i++) {
    console.log(i);
    continue;
}
// loop2.js
var i = 0;
while(i < 10) {
    if (i === 8) continue;
    console.log(i);
    i++;
}

两个看似一样的循环。其实第一个循环会打印出0 1 2 3 4 5 6 7 8 9的数字。而第二个则打印到7的时候就进入无限循环了。这表明了for循环在使用continue的时候先执行了for语句中的递增语句然后才进行条件判断。而while循环中则直接进行条件判断了。使用这两个循环语句的时候请小心这个特性。

说到这里必须要提一提我们的异常处理

3.finally语句的一些奇怪特性

如果finally从句运行到了return语句,尽管已经抛出异常且这个异常还没有处理,这个方法依然会正常返回。

这感觉又是一个坑啊。

// exception.js
var foo = function() {
    try {
        throw Error();
    } finally {
        return 1;
    }
}

console.log(foo());

你要知道这个东西最后得出的结果是

1

它并没有理会抛出的错误而是正常返回了。汗!!!
为此有些丧心病狂的人还想采用这种特性用while来模拟for循环的行为。

// loop3.js
var i = 0;
while(i < 10) {
    try {
        if (i == 8) continue;
        console.log(i);
    } finally {
        i ++;
    }
}

这看起来是没什么问题。无论怎样while循环都会执行increment语句了。这似乎已经解决了while循环中包含continue的话直接跳到测试语句的问题。continue语句直接跳转到finally执行递增语句。这行为似乎跟for相同了。

But,如果我们try语句里面包含的是break的话。放在for循环看则会直接退出。而加入了trywhile循环则会执行了increment操作之后才退出循环。

-_-最后,他们有了这个结论。

即便使用了finally,用while来完全模拟for循环依然是不可能的。

几个个比较简单的东西好像也说了不少。下次会控制篇幅,感谢你能看到这里。

Happy Coding !!

    原文作者:lanzhiheng
    原文地址: https://www.jianshu.com/p/aa5b788b3418
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞