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