摘要:上面這段代碼,在中的執(zhí)行結(jié)果是什么呢大家思考分鐘好,分鐘已過(guò),大家有結(jié)果了嗎千萬(wàn)不要在瀏覽器的控制臺(tái)中去寫這段代碼,雖然結(jié)果和你開始想的結(jié)果一樣,但是,它是錯(cuò)誤的。這是在控制臺(tái)中執(zhí)行的結(jié)果這是在中的執(zhí)行結(jié)果可以看到兩個(gè)結(jié)果是不一樣的。
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");
我想要當(dāng) j = 2 的時(shí)候就退出所有的for語(yǔ)句,打印最后的 done ,你會(huì)怎么做?
可能有的同學(xué)會(huì)想到這樣:
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");
這樣可以實(shí)現(xiàn),但是又多寫了一個(gè)函數(shù),那么有沒(méi)有別的辦法呢?
再看一個(gè)例子,你也一定見(jiàn)到過(guò)這樣的寫法:
// 假設(shè)str是你通過(guò)ajax接收到的JSON串 var str = "{"name": "liu", "age": 20}"; var obj = eval("(" + str + ")"); console.log(obj);
那么,你有沒(méi)有想過(guò) eval 里面為什么要加上括號(hào)呢?如果不加又是什么情況?(提前劇透,不加括號(hào)這里會(huì)報(bào)錯(cuò)哦)。
接著往下看,當(dāng)你讀完這篇文章的時(shí)候,心中的疑惑會(huì)完全解開。
2. Label Statement學(xué)過(guò)C語(yǔ)言的同學(xué)知道,C的語(yǔ)法中有一個(gè)語(yǔ)句叫:goto,同時(shí)老師也多次強(qiáng)調(diào)不讓我們使用goto語(yǔ)句,因?yàn)闀?huì)大大影響程序的可讀性和可維護(hù)性。
我們先來(lái)看一段C語(yǔ)言的goto代碼:
void main(){ int a=2, b=3; if(a>b) { goto aa; } printf("hello"); aa: printf("s"); return 0; }
當(dāng) a < b 的時(shí)候,這里會(huì)打印字符串 "hello",然后結(jié)束。
當(dāng) a > b 的時(shí)候,由于goto語(yǔ)句的作用,就會(huì)跳過(guò) print("hello"),直接跳到 aa 標(biāo)簽聲明的代碼塊中,打印字符 "s",然后結(jié)束。
這就是goto語(yǔ)句的作用,通過(guò)標(biāo)簽聲明一個(gè)代碼塊,然后在任何地方都可以執(zhí)行 goto "labe" 來(lái)進(jìn)行程序跳轉(zhuǎn)。
顯而易見(jiàn),這樣的寫法,違背了程序順序執(zhí)行的原則,會(huì)跳來(lái)跳去,最后導(dǎo)致根本無(wú)法維護(hù),所以,記住老師的話,不要使用 goto 語(yǔ)句。
那么,看完了C語(yǔ)言中的 goto 語(yǔ)句,和我們的 JavaScript 又有什么關(guān)系呢?
這就引出了今天的主題:Label Statement,它就是 JS 中的 goto 語(yǔ)句。
首先明確一個(gè)原則,在JavaScript中,語(yǔ)句優(yōu)先。
也就是說(shuō),如果一段代碼既能夠以語(yǔ)句的方式解析,也能用語(yǔ)法的方式解析,在JS中,會(huì)優(yōu)先按語(yǔ)句來(lái)解析。
{ a : 1 }
上面這段代碼,在JS中的執(zhí)行結(jié)果是什么呢?
大家思考2分鐘....
好,2分鐘已過(guò),大家有結(jié)果了嗎?
千萬(wàn)不要在瀏覽器的控制臺(tái)中去寫這段代碼,雖然結(jié)果和你開始想的結(jié)果一樣,
但是,它是錯(cuò)誤的。
這是在console控制臺(tái)中執(zhí)行的結(jié)果:
這是在watch中的執(zhí)行結(jié)果:
可以看到兩個(gè)結(jié)果是不一樣的。
console是經(jīng)過(guò)處理的這里不能相信,watch是直接JS的運(yùn)行環(huán)境執(zhí)行后的結(jié)果,是正確的。
為什么 { a : 1 } 結(jié)果會(huì)是 1 呢?
我換一個(gè)寫法:
{ a : 1 }
相信有的同學(xué)已經(jīng)明白了,在JS中,{}既可以代表代碼塊,又可以作為Object的語(yǔ)法標(biāo)志。
那么我們前面說(shuō)過(guò),JS是語(yǔ)句優(yōu)先的,當(dāng)一段代碼既可以按照語(yǔ)句解析,又可以按照語(yǔ)法解析的時(shí)候,會(huì)優(yōu)先按語(yǔ)句解析。
當(dāng)把{}當(dāng)做是代碼塊的時(shí)候,里面的 a : 1,是不是很像C語(yǔ)言goto語(yǔ)句的標(biāo)簽聲明呢?
開頭我們提出的第一個(gè)問(wèn)題,如果用這種方式來(lái)解決,代碼如下:
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是標(biāo)簽聲明,包裹一個(gè)代碼塊,break 的作用是跳出當(dāng)前的循環(huán),本來(lái)是無(wú)法跳出外面那層for循環(huán)的,但是 break aa,這里跳出了整個(gè)代碼塊。
當(dāng)然,這種寫法是完全不提倡的,這里只是用來(lái)說(shuō)明JS中的Label Statement這個(gè)特性,大家千萬(wàn)不要這樣寫代碼。
再來(lái)看開頭提出的第二個(gè)問(wèn)題:
// 假設(shè)str是你通過(guò)ajax接收到的JSON串 var str = "{"name": "liu", "age": 20}"; var obj = eval("(" + str + ")"); console.log(obj);
我們知道,eval(str)會(huì)把接收到的字符串在當(dāng)前上下文中執(zhí)行,如果不加括號(hào):
eval("{"name": "liu", "age": 20}}")
這里的執(zhí)行語(yǔ)句就會(huì)變成:
{ "name" : "liu", "age" : 20 }
{}按照語(yǔ)句解析,執(zhí)行里面的逗號(hào)表達(dá)式,我們知道逗號(hào)表達(dá)式要求每一項(xiàng)都必須是表達(dá)式,輸出最后一項(xiàng)的結(jié)果,而這里不滿足要求,所以會(huì)報(bào)錯(cuò)。
但是加上括號(hào)就變成了這樣:
({ "name" : "liu", "age" : 20 })
小括號(hào)可以把里面的內(nèi)容當(dāng)做表達(dá)式來(lái)解析,那么里面的內(nèi)容就是一個(gè)對(duì)象了。
這也是立即執(zhí)行函數(shù)的原理:
(function () { console.log("IIFE"); })()
小括號(hào)把函數(shù)聲明變成了函數(shù)表達(dá)式,后面再跟一個(gè)小括號(hào)表示調(diào)用。
4. 結(jié)束這里通過(guò)幾個(gè)例子,引出了 JavaScript 的標(biāo)簽聲明語(yǔ)句(Label Statement),從而解釋了一些我們常用寫法的原理。
以后萬(wàn)一有人問(wèn)你為什么 eval() 解析JSON要加括號(hào)呢?
這回知道怎么說(shuō)了吧。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93897.html
摘要:表達(dá)式用來(lái)計(jì)算出一個(gè)值,語(yǔ)句用來(lái)執(zhí)行以使某件事發(fā)生。其中,語(yǔ)句會(huì)立即退出循環(huán),強(qiáng)制繼續(xù)執(zhí)行循環(huán)后面的語(yǔ)句。在執(zhí)行語(yǔ)句之后,結(jié)果顯示。語(yǔ)句語(yǔ)句的作用是指定函數(shù)調(diào)用后的返回值。語(yǔ)句語(yǔ)句的作用是把程序運(yùn)行時(shí)產(chǎn)生的錯(cuò)誤顯式地拋出異常。 表達(dá)式在 JavaScript 中是短語(yǔ),那么語(yǔ)句就是整句命令。表達(dá)式用來(lái)計(jì)算出一個(gè)值,語(yǔ)句用來(lái)執(zhí)行以使某件事發(fā)生。從本質(zhì)上看,語(yǔ)句定義了 JavaScript...
摘要:表達(dá)式語(yǔ)句把表達(dá)式當(dāng)做語(yǔ)句的用法聲明語(yǔ)句用來(lái)聲明新變量或定義新函數(shù)控制結(jié)構(gòu)改變語(yǔ)句的默認(rèn)執(zhí)行順序條件語(yǔ)句循環(huán)語(yǔ)句跳轉(zhuǎn)語(yǔ)句表達(dá)式語(yǔ)句賦值語(yǔ)句運(yùn)算符函數(shù)調(diào)用等復(fù)合語(yǔ)句和空語(yǔ)句復(fù)合語(yǔ)句復(fù)合語(yǔ)句將多條語(yǔ)句聯(lián)合在一起,當(dāng)成一條單獨(dú)的語(yǔ)句語(yǔ)句塊的結(jié)尾不 表達(dá)式語(yǔ)句(expression statement):把表達(dá)式當(dāng)做語(yǔ)句的用法; 聲明語(yǔ)句(declaration statement):用來(lái)聲...
摘要:系列文章核心概念本文淺嘗最近因?yàn)楣ぷ魃闲庐a(chǎn)品的需要,讓我有機(jī)會(huì)了解和嘗試。這篇文章主要分享的是的核心概念,主要分為和四部分。再次強(qiáng)調(diào),本文主要講的是的核心概念,中所定義的類,都是設(shè)計(jì)類,并不是具體實(shí)現(xiàn)代碼。 A query language created by Facebook for describing data requirements on complex applicati...
摘要:通過(guò)增加刪除元素改變布局的。譬如和控制元素顯示隱藏,或者改變?cè)匦袨榈?。譬如設(shè)計(jì)看過(guò)我之前介紹以手寫依賴注入的朋友應(yīng)該已經(jīng)對(duì)行為驅(qū)動(dòng)多少有些了解了。她有,并且包含了至少一個(gè)和一個(gè)標(biāo)簽。,將左邊的事件傳遞給了右邊的表達(dá)式通常就是事件處理函數(shù)。 前集回顧 在上一章里我們講了如何為angular2搭建開發(fā)環(huán)境(還沒(méi)搭起來(lái)的趕緊去看哦),并使之跑起來(lái)我們的第一個(gè)My First Angular...
摘要:前言基本上,我們每天都在和中的各種語(yǔ)句進(jìn)行著溝通,那些我們經(jīng)常見(jiàn)面的老朋友,或者是未曾見(jiàn)面的新朋友,它們共同維護(hù)著的流程,讓我們的程序穩(wěn)步運(yùn)行。 前言 基本上,我們每天都在和 JavaScript 中的各種語(yǔ)句進(jìn)行著 溝通 ,那些我們經(jīng)常見(jiàn)面的 老朋友,或者是未曾見(jiàn)面的 新朋友 ,它們共同維護(hù)著 JavaScript 的流程,讓我們的程序穩(wěn)步運(yùn)行。那么,你是否對(duì)它們足夠了解呢 如果文章...
閱讀 1151·2021-11-25 09:43
閱讀 1583·2021-10-25 09:47
閱讀 2478·2019-08-30 13:46
閱讀 764·2019-08-29 13:45
閱讀 1292·2019-08-26 13:29
閱讀 3000·2019-08-23 15:30
閱讀 1113·2019-08-23 14:17
閱讀 1336·2019-08-23 13:43