摘要:盡管如此,由于塊作用域的緣故,這段代碼還是能夠安全地運行。塊作用域的顯式聲明如何避免上述問題呢答案是利用額外的一對大括號來做塊作用域的顯式聲明。
ES2015已經定稿一年多了,想必大家早就用上let和const來充分利用塊作用域的優(yōu)勢了吧?那么,你們知道塊作用域都是怎么聲明的嗎?
在各種教程資料的例子里,塊作用域都是出現(xiàn)在for(……){……}/if(……){……}/while(……){……}這些語句里的,那你有沒有想過,塊作用域其實跟這些邏輯控制語句完全沒有關系?
前置知識本文需要有塊作用域以及let / const相關知識,如有欠缺,請看這里。
塊作用域的標識塊作用域的標識其實是那一對大括號{},換句話說,我們不需要任何邏輯控制語句就可以直接使用大括號來創(chuàng)建塊作用域:
var a = 2; { let a = 3; } console.log(a); // 輸出2塊作用域的隱式聲明
相信大家一般都不會直接用大括號來創(chuàng)建塊作用域,而是像下面這個例子來使用:
var a = 2; var b = 2; var c = 0; if (a === b) { let c = 2; a ++; b -= c; } console.log(a); // 3 console.log(b); // 0
你可能注意到,這段代碼里定義了兩個變量c,這有時并不是故意重復起名為c,而是前面一大堆代碼,根本不知道變量名c已經被用掉了。盡管如此,由于塊作用域的緣故,這段代碼還是能夠安全地運行。
但如果這段代碼由別人接手,而他又急于改需求呢,那很可能就會出現(xiàn)以下這種情況:
var a = 2; var b = 2; var c = 0; if (a === b) { let c = 2; a ++; } b -= c; console.log(a); // 3 console.log(b); // 2
需求是這樣改的:不需要判斷a === b就執(zhí)行b -= c;了。此時,這段代碼在運行時也不會報錯(因為前面早已定義有了一個同名變量c),但結果卻出錯了,而且往往這種錯誤還不容易發(fā)現(xiàn)。
塊作用域的顯式聲明如何避免上述問題呢?答案是:利用額外的一對大括號來做塊作用域的顯式聲明。
我們試著用塊作用域的顯式聲明來修改上述代碼:
var a = 2; var b = 2; var c = 0; if (a === b) { { // 使用大括號來包裹住塊作用域變量相關的代碼塊 let c = 2; b -= c; } a ++; // 操作的都是塊作用域外部就定義好的變量,剔除在大括號以外 } console.log(a); // 3 console.log(b); // 0
看著有點別扭是吧?沒關系,我們看看按需求修改后的代碼:
var a = 2; var b = 2; var c = 0; if (a === b) { a ++; } { let c = 2; b -= c; } console.log(a); // 3 console.log(b); // 0
duang!
爸爸媽媽再也不用擔心我重構代碼的時候出一大堆bug了!
總結塊作用域的顯式聲明實際上是主動分隔開接受塊作用域管理的let / const變量和不接受塊作用域管理的var變量,從而幫助我們在重構代碼時,能更輕松、更放心地挪動代碼。
本文首發(fā)于Array_Huang的技術博客——實用至上,非經作者同意,請勿轉載。
原文地址:https://segmentfault.com/a/1190000007639527
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/91171.html
摘要:提供了同時解決這兩個問題的方案以上這種模式稱為立即執(zhí)行函數表達式。塊作用域不應該完全作為函數作用域的替代方案,兩種功能應該同時存在。 函數作用域 為了隱藏內部實現(xiàn),可以通過在任意代碼片段外部添加包裝函數,但是這并不理想,因為必須聲明一個具名函數,意味著這個函數名稱本身會污染函數所在的作用域;同時必須通過顯式地調用函數才能運行其中的代碼。 *:區(qū)分函數聲明和表達式最簡單的方法是看func...
摘要:塊級作用域中的塊級作用域很有可能導致局部變量覆蓋全局變量或者局部變量泄露成全局變量。也就是局部變量與全局變量不會打架塊級作用域的出現(xiàn),實際上使得獲得廣泛應用的立即執(zhí)行匿名函數不再必要了。 let 和 const命令 1.let 命令 基本用法 語法類似 var,但是所聲明的變量,只在 let 命令所在的代碼塊內有效。 在 for 循環(huán)中,就非常適合使用 let 聲明變量。 var a...
摘要:大家好,我從今天開始就會正式講的語法方面。變量中的變量一般使用來聲明的不在本教程討論范圍內,可以用來定義任何種類的變量,如果只對變量進行了定義而沒有賦值,這樣變量會默認為。 大家好,我從今天開始就會正式講javascript的語法方面。變量 js中的變量一般使用var來聲明(es6的let不在本教程討論范圍內),可以用來定義任何種類的變量,如果只對變量進行了定義而沒有賦值,這樣變量會默...
摘要:大家好,我從今天開始就會正式講的語法方面。變量中的變量一般使用來聲明的不在本教程討論范圍內,可以用來定義任何種類的變量,如果只對變量進行了定義而沒有賦值,這樣變量會默認為。 大家好,我從今天開始就會正式講javascript的語法方面。變量 js中的變量一般使用var來聲明(es6的let不在本教程討論范圍內),可以用來定義任何種類的變量,如果只對變量進行了定義而沒有賦值,這樣變量會默...
摘要:全局作用域在任何函數塊或模塊范圍之外定義的變量具有全局作用域。的局部函數作用域是函數的詞法作用域。作用域鏈每個作用域都有一個指向父作用域的鏈接。當使用變量時,會向下查看作用域鏈,直到它找到所請求的變量或者到達全局作用域即作用域鏈的末尾。 一網打盡 JavaScript 的作用域 翻譯:瘋狂的技術宅https://medium.freecodecamp.o...??-javascript...
閱讀 1441·2021-11-25 09:43
閱讀 2044·2021-07-26 23:38
閱讀 751·2019-08-30 15:53
閱讀 2289·2019-08-30 15:43
閱讀 1180·2019-08-29 18:40
閱讀 1981·2019-08-26 13:28
閱讀 1983·2019-08-23 18:20
閱讀 555·2019-08-23 15:07