1.標(biāo)簽跳轉(zhuǎn)
類似于C語言里面有g(shù)oto語句瘪阁,JavaScript里面有個(gè)語句跳轉(zhuǎn)的玩意兒操禀,叫做標(biāo)簽跳轉(zhuǎn)隧枫。不過它沒有C語言這么夸張纬乍,C語言好像設(shè)定是可以跳轉(zhuǎn)到函數(shù)內(nèi)任意的地方第晰。我們先來看一個(gè)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;
}
很遺憾這里是一個(gè)無限循環(huán)。會(huì)不斷打印出Hello Lan
, Hello World
, 0
但荤。在tag
與goto
之間還是可以存在有挺多語句的罗岖。這樣給C語言帶來了不少麻煩。所以就算是C語言的作者也不建議我們使用goto
語句腹躁。如果太多這類跳轉(zhuǎn)只會(huì)徒增代碼維護(hù)的成本桑包。(更可怕的是Review你代碼的人可能會(huì)拿著菜刀來追你!!)
于此相對(duì)應(yīng)的Javascript的跳轉(zhuǎn)有節(jié)操很多。標(biāo)簽只定義在條件語句或者循環(huán)語句前面, 而且如果標(biāo)簽與目標(biāo)語句之間還有額外的語句纺非,就不能通過解釋器哑了。我們只能從條件語句或者循環(huán)語句內(nèi)部通過continue
, break
兩個(gè)關(guān)鍵字進(jìn)行跳轉(zhuǎn)。烧颖。不再多說弱左,舉幾個(gè)栗子就很好理解了。
// 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);
打印的結(jié)果是:
value of a is: 100
value of b is: 11
value of c is: 90
continue
跳轉(zhuǎn)tag會(huì)跳轉(zhuǎn)到tag的位置炕淮,然后繼續(xù)執(zhí)行對(duì)應(yīng)的循環(huán)拆火。(因?yàn)闂l件語句里面也用不了continue),而break
跳轉(zhuǎn)tag會(huì)終止tag所指示的循環(huán)語句或者條件語句的運(yùn)行涂圆。
這里我們tag1用了continue
所以它會(huì)跳轉(zhuǎn)到tag1然后繼續(xù)執(zhí)行while循環(huán)们镜,直到a>=100
才退出循環(huán)。而我們tag2處用了break
润歉,直接結(jié)束了tag2所指示的語句模狭。我們只執(zhí)行了一次b++
所以得到了11
這個(gè)結(jié)果。
不能夠在標(biāo)簽與指定語句之間添加其他語句踩衩,或者在條件以及循環(huán)以外的情景打標(biāo)簽嚼鹉。下面是錯(cuò)誤示范
// error1.js
var d = 10;
tag4:
// 在標(biāo)簽與想指定的循環(huán)之間插入語句贩汉。
console.log("good");
while(d < 100) {
d++;
if (d == 90) break tag3;
}
console.log("value of d is: " + d);
// error2.js
// 對(duì)函數(shù)打標(biāo)簽, 這條也是錯(cuò)誤的語法
tag:function errorFun() {
console.log("good");
break tag;
}
上面的語句都是無法通過解釋器的。只是作為反面教材锚赤。請(qǐng)大家謹(jǐn)慎
了匹舞。總的來說Javascript的跳轉(zhuǎn)相比于C可維護(hù)性方面還是稍微高了點(diǎn)宴树。畢竟限制多了策菜。大家酌情使用吧。
2.continue語句對(duì)于for跟while兩種循環(huán)會(huì)有不同的行為
continue語句在while循環(huán)中直接進(jìn)入下一輪循環(huán)酒贬。而在for循環(huán)中使用則先計(jì)算
increment
表達(dá)式又憨,然后再進(jìn)行循環(huán)條件判斷。
-_-這聽起來就是個(gè)坑嘛锭吨。
我還是舉例子說明一下
// 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++;
}
兩個(gè)看似一樣的循環(huán)蠢莺。其實(shí)第一個(gè)循環(huán)會(huì)打印出0 1 2 3 4 5 6 7 8 9
的數(shù)字。而第二個(gè)則打印到7
的時(shí)候就進(jìn)入無限循環(huán)了零如。這表明了for
循環(huán)在使用continue的時(shí)候先執(zhí)行了for語句中的遞增語句然后才進(jìn)行條件判斷躏将。而while
循環(huán)中則直接進(jìn)行條件判斷了。使用這兩個(gè)循環(huán)語句的時(shí)候請(qǐng)小心這個(gè)特性考蕾。
說到這里必須要提一提我們的異常處理
3.finally語句的一些奇怪特性
如果finally從句運(yùn)行到了return語句祸憋,盡管已經(jīng)拋出異常且這個(gè)異常還沒有處理,這個(gè)方法依然會(huì)正常返回肖卧。
這感覺又是一個(gè)坑啊蚯窥。
// exception.js
var foo = function() {
try {
throw Error();
} finally {
return 1;
}
}
console.log(foo());
你要知道這個(gè)東西最后得出的結(jié)果是
1
它并沒有理會(huì)拋出的錯(cuò)誤而是正常返回了。汗!!!
為此有些喪心病狂的人還想采用這種特性用while
來模擬for
循環(huán)的行為塞帐。
// loop3.js
var i = 0;
while(i < 10) {
try {
if (i == 8) continue;
console.log(i);
} finally {
i ++;
}
}
這看起來是沒什么問題拦赠。無論怎樣while
循環(huán)都會(huì)執(zhí)行increment語句了。這似乎已經(jīng)解決了while
循環(huán)中包含continue
的話直接跳到測(cè)試語句的問題葵姥。continue
語句直接跳轉(zhuǎn)到finally
執(zhí)行遞增語句荷鼠。這行為似乎跟for相同了。
But榔幸,如果我們try
語句里面包含的是break
的話允乐。放在for
循環(huán)看則會(huì)直接退出。而加入了try
的while
循環(huán)則會(huì)執(zhí)行了increment操作之后才退出循環(huán)削咆。
-_-最后喳篇,他們有了這個(gè)結(jié)論。
即便使用了finally态辛,用while來完全模擬for循環(huán)依然是不可能的。
幾個(gè)個(gè)比較簡(jiǎn)單的東西好像也說了不少挺尿。下次會(huì)控制篇幅奏黑,感謝你能看到這里炊邦。