for (let i = 0; i < 100; i++) { if (i === 50) break; }
相信你們在使用break
的場景是相似上面的場景,在for循環中在特定的判斷下跳出循環。chrome
相信你們都在console上這樣操做過,輸入這些語句的結果到底是什麼。
答案是Completion Record
Completion Record
是EMCScript標準中的一個規範類型。
它長這個樣子函數
{ [[Type]]: normal | continue | break | return | throw [[Value]]: 語句執行的結果,若是沒有則是empty [[Target]]: 控制流的轉移目標,一般是標籤 }
語句的執行都會產生一個Completion Record
在一個Block中,也會返回一個Completion Record
spa
{ let a = 1; // 1 console.log(a); // 2 ++2; // 3 console.log(a); // 4 }
你們直接把上面的代碼複製在chrome 的console中而後執行,看結果是什麼?
結果是2
,如今咱們逐步分析一下
在上面的塊級做用域中,位置1產生的Completion Record
是code
[[Type]]: normal, [[Value]]: empty, [[target]]: nothing
按照上面的邏輯,位置2的[[Value]]
是empty
位置3的[[Value]]
是2
位置4的[[Value]]
是empty
empty不會覆蓋以前的結果
因此整個塊級做用域的執行結果是2orm
如今有一個提案是do表達式blog
const w = do { let a = 1; ++2; };
可以獲取塊級做用域Completion Record
的[[Value]]
若是這個提案經過的話,以後的JSX將拋棄長長的三目判斷
ip
上面這個代碼,若是執行foo函數輸出的內容是什麼?
在 try中進行return,因爲存在finally,而finally不管如何都是須要被執行的,因此try的Completion Record
是作用域
[[Type]]: return, [[Value]]: 100, [[target]]: nothing
執行到finally的時候,整個try-catch-finally代碼塊的Completion Record
是get
[[Type]]: break, [[Value]]: empty, [[target]]: bbb
因此return會被break覆蓋
最終返回的i是101it