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
。在tag
与goto
之间还是可以存在有挺多语句的。这样给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
循环看则会直接退出。而加入了try
的while
循环则会执行了increment操作之后才退出循环。
-_-最后,他们有了这个结论。
即便使用了finally,用while来完全模拟for循环依然是不可能的。
几个个比较简单的东西好像也说了不少。下次会控制篇幅,感谢你能看到这里。
网友评论