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