关于ECMAScript规范中Abstract Operations的相关技术问题
关于ECMAScript抽象操作的三个问题解答
Abstract Operations不属于ECMAScript语言的组成部分,此处对其进行定义的唯一目的是辅助规范ECMAScript语言的语义
1. “唯一目的是辅助规范”的具体含义是什么?
这句话的核心是明确抽象操作的定位:它不是ECMAScript对外提供的语法、API或者语言特性,只是TC39在编写规范时用到的统一描述工具。
ECMAScript里有大量内置语法、API的底层逻辑是高度重合的,比如「把任意值转为布尔值」「判断一个值是否是可调用的函数」这类操作,在几十上百个不同的内置逻辑里都会用到。如果每个地方都把这些逻辑重写一遍,规范不仅会极其臃肿,还很容易出现不同章节描述不一致的问题。所以TC39把这些公共逻辑抽出来统一定义为抽象操作,编写规范时直接引用对应的抽象操作即可,既精简了规范内容,也能保证所有语言行为的定义是完全一致的。
2. 如果抽象操作不属于语言组成部分,为何可以被实际使用?
这里存在一个普遍的认知误区:普通开发者根本无法直接调用规范中定义的抽象操作,你感知到的「可以使用」本质是上层API的行为和抽象操作的定义对齐了。
比如规范里定义的抽象操作ToPrimitive,你不能在JS代码里直接写ToPrimitive(xxx)调用它,但你用+ '123'隐式类型转换、或者调用String(xxx)的时候,引擎内部的执行逻辑完全遵循ToPrimitive的定义。你用到的是符合抽象操作逻辑的上层语法/API,不是抽象操作本身。
3. 其可用性是否取决于JavaScript引擎的实现?
抽象操作本身不会暴露给开发者,所以不存在面向开发者的「可用性」说法。
但所有符合ECMAScript规范的JavaScript引擎,都必须保证所有对外暴露的语法、API的执行结果,和规范用抽象操作描述的结果完全一致。至于引擎内部是直接照着抽象操作的逻辑实现,还是做了等价的性能优化,完全由引擎团队自己决定,只要最终表现和规范对齐即可。如果某款引擎的执行结果和抽象操作定义的结果不一致,就属于引擎的实现bug,不符合ECMAScript标准。
内容的提问来源于stack exchange,提问作者pso

