label 0x0:Vue Ref 提案
近日,Vue 作者在社區提交了一份Ref 語法糖的提案,引發了社區的爭議。
關於 Ref 提案,它是將原本應該使用 ref() 調用的方式,通過 label 語法 ref: 進行簡化編寫,並在編譯期間進行轉換,所以這個本質上是個語法糖,示例如下,
原寫法:
|
|
新提案寫法:
|
|
這個提議最大的爭議在於,新提案的寫法是符合 JS 語法,但卻不符合 JS 的語義,按照 label 的語義,ref: count = 0 裏的 ref: 是無任何意義的,既在運行時不做解析,但在 Vue 的 script setup 下卻賦予了 ref() 的功能!
label 語法通常很少被使用,以至於部分人在看到新提案的寫法後認爲是 Vue 的新魔法,紛紛表示學不動或認爲應該將 Vue 的寫法叫 VueScript。
在看到 ref 提案後又回想起多年來未曾用過的 label 語法,本篇主要介紹及回顧下彙編、C、JavaScript 語言的 label 語法和使用。
label 0x1:彙編語言
彙編語言主要是彙編指令(語句)組成,一條指令有四個組成部分,如下:
|
|
示例:
|
|
標號(label)是一種標識符,是指令的位置標記。標號位於指令的前端,表示指令的地址。
默認情況下,CPU 是順序加載並執行程序。但是,在實現類似條件跳轉、循環等功能時,就需要使用跳轉指令+lablel 來實現,彙編語言中有多種跳轉指令,這裏以 jmp 爲例,語法如下:
|
|
示例一:
|
|
示例二:
|
|
label 是僞指令,嵌入源代碼中的命令,由彙編器識別和執行,不在運行時執行。
label 0x2:C 語言
label 語法如下:
|
|
在彙編語言中將 label 當作指令的位置標記,C 語言中也是如此,C 語言使用 goto 語句配合跳轉到指定的 label 處,類似彙編的 jmp 效果,goto 語法如下:
|
|
示例
|
|
由於 goto 的自由和靈活,在程序上可隨意跳轉,在使用不當的情況下會破壞“結構化”,不但帶來編程的混亂,而且容易出錯,所以在很多語言教學上都不建議使用。
label 0x3:JavaScript 語言
label 語法如下:
|
|
語法同 C 語言,但是 JS 沒有 goto 語句,不能像 C、彙編那樣隨意跳轉,JS 的 label 語法只能配合 break、continue 進行使用,單獨使用時無意義。在 JS 裏 continue/break label 應該算是一個閹割版 goto 語句。
配合 continue 使用時,語法如下:
|
|
示例:
|
|
特別注意:continue label 後的 label 必須緊跟着 for、while 一起時纔可以,否則會報錯,如下:
|
|
配合 break 使用時,語法如下:
|
|
相比 continue ,break label 的使用靈活會更大,可以和 For、While、Switch、Block 語句配合,如下:
|
|
示例一:
|
|
示例二:
|
|
單獨使用 label
label 在不配合 continue、break 使用時無意義,解釋器會直接忽略 label,示例:
|
|
label 0x4:最後
label 語法在高級語言中的存在感都非常低,主要還是因爲高級語法已經提供了非常多的控制語句,絕大部分場景下已經不需要使用 label、goto 這種相對直接的跳轉。label 的作用本質上還是代碼位置標記,以便類似 goto 的語句進行跳轉,雖然大部分情況都是不建議使用,但有時 goto 可以大幅度簡化代碼量(如:跳出多層嵌套,跳出多層循環場景),在保證代碼足夠清晰明確下,偶爾使用也是可以的。
回到文章開頭,關於 Vue Ref 提案之所以引起許多開發者的注意跟討論,主要還是因爲修改了 label 的語義,儘管符合 JS 語法,但爲 label 增添的非標準語義,會讓部分開發者陷入混亂,增加心智負擔。
討論傳送門:New script setup and ref sugar