JS學(xué)習(xí)系列 07 - 標簽聲明(Label Statement)

1. 引言

假設(shè)有這么一道題:

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

console.log('done');

我想要當 j = 2 的時候就退出所有的for語句瑞侮,打印最后的 done 谊娇,你會怎么做类垫?

可能有的同學(xué)會想到這樣:


function foo () {
    for (var i = 0; i < 10; i++) {
        console.log(i);
        for (var j = 0; j < 5; j++) {
            console.log(j);
            if (j === 2) return;
        }
    }
}

foo();

console.log('done');

這樣可以實現(xiàn),但是又多寫了一個函數(shù)惹悄,那么有沒有別的辦法呢?

再看一個例子肩钠,你也一定見到過這樣的寫法:

// 假設(shè)str是你通過ajax接收到的JSON串
var str = '{"name": "liu", "age": 20}';
var obj = eval('(' + str + ')');

console.log(obj); 

那么泣港,你有沒有想過 eval 里面為什么要加上括號呢?如果不加又是什么情況价匠?(提前劇透当纱,不加括號這里會報錯哦)。

接著往下看踩窖,當你讀完這篇文章的時候坡氯,心中的疑惑會完全解開。

2. Label Statement

學(xué)過C語言的同學(xué)知道洋腮,C的語法中有一個語句叫:goto箫柳,同時老師也多次強調(diào)不讓我們使用goto語句,因為會大大影響程序的可讀性可維護性啥供。

我們先來看一段C語言的goto代碼:

void main(){
    int a=2, b=3;
    
    if(a>b) {
        goto aa;
    }
    
    printf("hello");
    
    aa: printf("s"); 
    
    return 0;
}

當 a < b 的時候滞时,這里會打印字符串 "hello",然后結(jié)束滤灯。
當 a > b 的時候坪稽,由于goto語句的作用,就會跳過 print("hello")鳞骤,直接跳到 aa 標簽聲明的代碼塊中窒百,打印字符 "s",然后結(jié)束豫尽。

這就是goto語句的作用篙梢,通過標簽聲明一個代碼塊,然后在任何地方都可以執(zhí)行 goto 'labe' 來進行程序跳轉(zhuǎn)美旧。

顯而易見渤滞,這樣的寫法,違背了程序順序執(zhí)行的原則榴嗅,會跳來跳去妄呕,最后導(dǎo)致根本無法維護,所以嗽测,記住老師的話绪励,不要使用 goto 語句肿孵。

那么,看完了C語言中的 goto 語句疏魏,和我們的 JavaScript 又有什么關(guān)系呢停做?
這就引出了今天的主題:Label Statement,它就是 JS 中的 goto 語句大莫。

3. 用法

首先明確一個原則蛉腌,在JavaScript中,語句優(yōu)先只厘。
也就是說眉抬,如果一段代碼既能夠以語句的方式解析,也能用語法的方式解析懈凹,在JS中蜀变,會優(yōu)先按語句來解析。

{ a : 1 }

上面這段代碼介评,在JS中的執(zhí)行結(jié)果是什么呢库北?
大家思考2分鐘....



好,2分鐘已過们陆,大家有結(jié)果了嗎寒瓦?
千萬不要在瀏覽器的控制臺中去寫這段代碼,雖然結(jié)果和你開始想的結(jié)果一樣坪仇,
但是杂腰,它是錯誤的。

這是在console控制臺中執(zhí)行的結(jié)果:

label-console圖片

這是在watch中的執(zhí)行結(jié)果:

clipboard.png

可以看到兩個結(jié)果是不一樣的椅文。
console是經(jīng)過處理的這里不能相信喂很,watch是直接JS的運行環(huán)境執(zhí)行后的結(jié)果,是正確的皆刺。

為什么 { a : 1 } 結(jié)果會是 1 呢少辣?

我換一個寫法:

{
    a : 1
}

相信有的同學(xué)已經(jīng)明白了,在JS中羡蛾,{}既可以代表代碼塊漓帅,又可以作為Object的語法標志。
那么我們前面說過痴怨,JS是語句優(yōu)先的忙干,當一段代碼既可以按照語句解析,又可以按照語法解析的時候浪藻,會優(yōu)先按語句解析捐迫。

當把{}當做是代碼塊的時候,里面的 a : 1珠移,是不是很像C語言goto語句的標簽聲明呢弓乙?
開頭我們提出的第一個問題,如果用這種方式來解決钧惧,代碼如下:

aa : {
    for (var i = 0; i < 10; i++) {
        console.log(i);
        for (var j = 0; j < 5; j++) {
            console.log(j);
            if (j === 2) break aa;
        }
    }
}

console.log('done');

aa是標簽聲明暇韧,包裹一個代碼塊,break 的作用是跳出當前的循環(huán)浓瞪,本來是無法跳出外面那層for循環(huán)的懈玻,但是 break aa,這里跳出了整個代碼塊乾颁。

當然涂乌,這種寫法是完全不提倡的,這里只是用來說明JS中的Label Statement這個特性英岭,大家千萬不要這樣寫代碼湾盒。

再來看開頭提出的第二個問題:

// 假設(shè)str是你通過ajax接收到的JSON串
var str = '{"name": "liu", "age": 20}';
var obj = eval('(' + str + ')');

console.log(obj); 

我們知道,eval(str)會把接收到的字符串在當前上下文中執(zhí)行诅妹,如果不加括號:

eval('{"name": "liu", "age": 20}}')

這里的執(zhí)行語句就會變成:

{
    "name" : "liu", "age" : 20
}

{}按照語句解析罚勾,執(zhí)行里面的逗號表達式,我們知道逗號表達式要求每一項都必須是表達式吭狡,輸出最后一項的結(jié)果尖殃,而這里不滿足要求,所以會報錯划煮。

label-watch2

但是加上括號就變成了這樣:

({
    "name" : "liu", "age" : 20
})

小括號可以把里面的內(nèi)容當做表達式來解析送丰,那么里面的內(nèi)容就是一個對象了。

label-watch2

這也是立即執(zhí)行函數(shù)的原理:

(function () {
    console.log('IIFE');
})()

小括號把函數(shù)聲明變成了函數(shù)表達式弛秋,后面再跟一個小括號表示調(diào)用器躏。

4. 結(jié)束

這里通過幾個例子,引出了 JavaScript 的標簽聲明語句(Label Statement)蟹略,從而解釋了一些我們常用寫法的原理邀桑。

以后萬一有人問你為什么 eval() 解析JSON要加括號呢?
這回知道怎么說了吧科乎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壁畸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茅茂,更是在濱河造成了極大的恐慌捏萍,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件空闲,死亡現(xiàn)場離奇詭異令杈,居然都是意外死亡,警方通過查閱死者的電腦和手機碴倾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門逗噩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掉丽,“玉大人,你說我怎么就攤上這事异雁〈氛希” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵纲刀,是天一觀的道長项炼。 經(jīng)常有香客問我,道長示绊,這世上最難降的妖魔是什么锭部? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮面褐,結(jié)果婚禮上拌禾,老公的妹妹穿的比我還像新娘。我一直安慰自己展哭,他們只是感情好蹋砚,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著摄杂,像睡著了一般坝咐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上析恢,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天墨坚,我揣著相機與錄音,去河邊找鬼映挂。 笑死泽篮,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的柑船。 我是一名探鬼主播帽撑,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鞍时!你這毒婦竟也來了亏拉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤逆巍,失蹤者是張志新(化名)和其女友劉穎及塘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锐极,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡笙僚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了灵再。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肋层。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡亿笤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出栋猖,到底是詐尸還是另有隱情净薛,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布掂铐,位于F島的核電站罕拂,受9級特大地震影響揍异,放射性物質(zhì)發(fā)生泄漏全陨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一衷掷、第九天 我趴在偏房一處隱蔽的房頂上張望辱姨。 院中可真熱鬧,春花似錦戚嗅、人聲如沸雨涛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽替久。三九已至,卻和暖如春躏尉,著一層夾襖步出監(jiān)牢的瞬間蚯根,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工胀糜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颅拦,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓教藻,卻偏偏與公主長得像距帅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子括堤,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)碌秸,也就是一...
    悟名先生閱讀 4,118評論 0 13
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多,請查閱幫助信息) 1悄窃、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,054評論 1 19
  • 個人學(xué)習(xí)批處理的初衷來源于實際工作哮肚;在某個迭代版本有個BS(安卓手游模擬器)大需求,從而在測試過程中就重復(fù)涉及到...
    Luckykailiu閱讀 4,691評論 0 11
  • 滅了燈广匙,黑暗如潮水般涌來允趟。打開手機,好友六十多個鸦致,被邀請加入的群N個潮剪,每個群都有大幾十甚至上百人涣楷,所有的全是信息免...
    飛雪如夢閱讀 232評論 0 0
  • 下面是稚雋教育小編為大家整理的一篇關(guān)于BMAT考試:寫作練習(xí)狮斗、范文及點評分享(2)的文章,供大家參考弧蝇,下面是詳細內(nèi)...
    peizhenjy閱讀 358評論 0 0