翻译本文的目的是尝试给出ECMAScript规范中核心术语的译法,供同好品评。

原文链接:https://timothygu.me/es-howto/

摘要

ECMAScript语言规范(又称JavaScript规范或ECMA-262)是学习JavaScript复杂工作原理的一手资料。然而,其浩繁的卷帙一开始总会让人无从下手、望而生畏。本文旨在降低阅读这一最佳JavaScript语言参考的阅读门槛。

目录

1. 前言
1.1 为什么应该阅读ECMAScript规范
1.2 什么属于ECMAScript规范,什么不属于
1.3 先别急,ECMAScript规范在哪里?
1.4 查阅规范

2. 运行时语义
2.1 算法步骤
2.2 抽象操作
2.3 什么是[This]
2.3.1 Record的字段
2.3.2 JavaScript对象的内部栏位
2.3.3 JavaScript对象的内部方法
2.4 完成记录:?!
2.5 JavaScript对象
2.6 示例:String.prototype.substring()
2.7 示例:Boolean()String()可以抛异常吗?
2.8 示例:typeof操作符

术语表
常见抽象操作

参考
参考资料

1. 前言

你肯定知道,每天读一点ECMAScript规范有益健康。无论它是你新年的小目标,还是仅仅为了遵照医嘱,反正欢迎阅读本文!

注意:本文只在指称规范是使用“ECMAScript”,其他地方使用“JavaScript”。不过,这两个词指的是同一个东西。(历史上,ECMAScript和JavaScript有一些区别,不过那不是本文的重点,大家可以自行搜索。)

1.1 为什么应该阅读ECMAScript规范

ECMAScript规范是实现JavaScript的权威资料,不管是在浏览器中,在Node.js中,还是在IoT设备中。所有JavaScript引擎的开发者都依靠这份文档确保自己的新特性能够跟其他JavaScript引擎一样如期工作。

不过必须得说明一下,规范的效用绝对不仅仅限于被称为“JavaScript引擎开发者”的那些神秘人物。实际上,规范对你我这样的普通JavaScript程序员一样有用,只是你还不知道罢了。

假如有一天你发现了下面这个问题:

> Array.prototype.push(42)
1
> Array.prototype
[ 42 ]
> Array.isArray(Array.prototype)
true
> Set.prototype.add(42)
TypeError: Method Set.prototype.add called on incompatible receiver #<Set>
    at Set.add (<anonymous>)
> Set.prototype
Set {}

并且想不通为什么一个方法可以对自己的原型起作用,而另一个方法却不能对自己的原型起作用。可惜谷歌总是在你最需要帮助时失灵,而一直给力的Stack Overflow居然也无能为力。

看规范可以找到答案。

或者,你可能就是想知道臭大街的松散相等操作符(==)到底怎么起作用。作为曾经勤奋好学的软件工程师,你在MDN上查到几段解释,但看来看去只会越来越晕。

看规范可以找到答案。

话说回来,我也不推荐JavaScript新手看ECMAScript规范。如果你才开始接触JavaScript,那还是先写几个网页或者Web应用吧!要不就写个基于JavaScript的保姆摄像头!别的什么东西也行!等你体会到足够多的JavaScript缺点,或者已经足够有钱而不必再担心JavaScript了,再回来看这篇文章不迟。

好啦,现在大家知道规范对于理解语言或平台的工作机制非常有帮助了。但要阅读ECMAScript规范,到底应该从哪里入手呢?

1.2 什么属于ECMAScript规范,什么不属于

1.3 先别急,ECMAScript规范在哪里?

谷歌“ECMAScript规范”,会看到很多结果,都说是合法规范。那应该看哪一个?

长话短说,tc39.es/ecma262/这个规范最可能是你想看的。

ECMAScript语言规范由具有不同背景的一群人共同制定,这群人就是TC39(即Ecma International Technical Committee 39)。TC39在tc39.es上面维护着ECMAScript语言的最新规范。

问题在于,TC39每年都会在某个时间点将规范的一个快照变成该年度的ECMAScript Language标准,并给它分配一个版本号。比如,ECMAScript® 2019 Language Specification (ECMA-262, 10th edition)(常被称为ES10或ES2019)就是2019年6月份在tc39.es上看到的规范,把它放福尔马林里那么一泡,一塑封并给出个PDF版,就永久封存了。

为此,除非你只想让自己的Web应用在2019年6月份之前发布的浏览器上跑,否则就应该只看tc39.es上最新的规范。但如果你想(或必须)支持旧版本浏览器或Node.js,那可能老版本规范有用。

ISO/IEC也把ECMAScript语言标准重新发布为ISO/IEC 22275。不过别担心,因为该标准基本上就是一个指向ECMAScript规范的超链接。

1.4 查阅规范

ECMAScript规范涉及的内容极多。即使规范的作者全力将它分成有逻辑的部分,仍然可以用卷帙浩繁来形容。

从个人角度,我喜欢将规范分成五部分。

  • 约定与基础(“什么是Nubmer?规范中说「抛出TypeError异常」时意味着什么?”)
  • 语言的文法产生式(“程序员应该怎么写for-in循环?”)
  • 语言的静态语义(“怎么确定var语句中的变量名?”)
  • 语言的运行时语义(如何执行for-in循环?
  • API(“String.prototype.substring()能做什么?”)

不过规范并不是这么组织的。事实上,它把第一个项目符号放在了“§5 表示方式约定”到“§9 普通与异质对象行”中,接下来三个项目符号穿插放在了“§10 ECMAScript语言:源代码”到“§15 ECMAScript语言:脚本与模块”中,比如:

  • §13.6 if语句文法产生式

    • §13.6.1-6 静态语义
    • §13.6.7 运行时语义
  • §13.7 迭代语句文法产生式

    • §13.7.1 共享的静态和运行时语义
    • §13.7.2 do-while语句

      • §13.7.2.1-5 静态语句
      • §13.7.2.6 运行时语义
    • §13.7.3 while语句
    • ……

而AP则分布在条款“§13 全局对象”到“§27 反射”中。

现在,我想说明一下,绝对没有人从头到尾地读规范。而是只会看与自己想寻找的答案相关的部分,而在该部分中则只看那些需要的地方。因此要学会判断你的问题与上述五大部分中的哪些相关。如果想不出来,可以问自己一个问题:“这个(你想确认的东西)是什么时间被求值的?”,应该有帮助。别担心,查规范查得越多就会越容易的。

2. 运行时语义

语言和API的运行时语义是规范中最大一部分,通常也是人们问题最多的地方。

总体来看,规范中这些部分都很直观明了。不过,规范使用的很多简写形式,让刚开始阅读的人(至少让我)感到很讨厌。接下来会解释一些这种约定,然后通过分析几个特性的原理来看看怎么使用它们。

2.1 算法步骤

ECMAScript中的大多数运行时语义都是通过一系列算法步骤规定的,不像伪代码,但更精确。

示例1

算法步骤的示例:

  1. a为1;
  2. ba+a
  3. b为2,则

    1. 哇!没算错。
  4. 否则

    1. 去!

继续阅读:“§5.2 算法约定”

2.2 抽象操作

有时候,你会看到一个类似函数调用的东西。Boolean()函数的第一步是:

2.3 什么是[This]

2.3.1 Record的字段

2.3.2 JavaScript对象的内部栏位

2.3.3 JavaScript对象的内部方法

2.4 完成记录:?!

2.5 JavaScript对象

2.6 示例:String.prototype.substring()

2.7 示例:Boolean()String()可以抛异常吗?

2.8 示例:typeof操作符

标签: none

添加新评论