跳到主要内容

JEP 292:在 Nashorn 中实现选定的 ECMAScript 6 功能

概括

在 Nashorn 中实现ECMA-262 第 6 版(也称为 ECMAScript 6,简称 ES6)中引入的一组选定的新功能。

目标

在 JDK 9 中的 Nashorn 中正确实现大量 ES6 功能。

由于这项工作的规模很大,我们需要分几个步骤交付 ES6,其中 JDK 9 只是第一步。剩余的 ES6 功能可能会在 JDK 9 更新版本和未来的主要 JDK 版本中提供。

动机

ECMAScript 6 于 2015 年 6 月发布。迄今为止,还没有 JavaScript 引擎提供对 ES6 的完整支持,但包括 Google V8、Mozilla Spidermonkey 和 JavaScriptCore 在内的主要引擎最近在ES6 的实现方面取得了重大进展。

我们开始使用JDK 8u40 中的JEP 203let和)在 Nashorn 中实现 ES6。const为了跟上其他引擎的步伐,我们计划在 JDK 9 中添加对 ECMAScript 6 功能的重要子集的支持。

描述

ECMAScript 6 包括以下新功能:

  • =>箭头函数:使用语法定义函数的简洁方法

  • 类:一种使用继承、构造函数和方法来定义类的方法

  • 增强的对象文字:支持特殊和计算属性键

  • 模板字符串:动态计算的多行字符串

  • 解构赋值:使用对象或数组语法进行赋值绑定

  • 默认、剩余和扩展参数:更灵活的参数传递

  • letconst和 块作用域:变量和常量的块作用域声明

  • 迭代器和for..of循环:迭代任意对象的协议

  • 生成器:一种创建迭代器的特殊函数

  • Unicode:完整的 Unicode 支持并向后兼容

  • 模块:对模块定义的语言级支持

  • 模块加载器:支持动态加载、隔离和编译钩子

  • MapSetWeakMapWeakSet:各种新的集合类

  • 代理:允许创建具有特殊行为的对象

  • 符号:一种新型的独特属性键

  • Array可子类化的内置函数:诸如和 之类的内置函数Date可以被子类化

  • Promises:用于异步未来完成的 API

  • MathNumberStringObjectAPI:内置对象的各种新功能

  • 二进制和八进制文字:数字文字的新形式

  • Reflection API:用于执行元编程操作的API

  • 尾部调用:允许递归代码而不会无限堆栈增长

我们已经在 JDK 8u40 中作为JEP 203实现了这些功能letconst块作用域。其他几个功能已经原型化,应该添加到 JDK 9 初始版本支持的 ES6 功能列表中。其中包括以下项目:

  • 模板字符串
  • letconst、 和块作用域
  • 迭代器和for..of循环
  • MapSetWeakMap, 和WeakSet
  • 符号
  • 二进制和八进制文字

其他功能已经部分原型化,并且似乎可以在有限的时间内完成。这些是 JDK 9 更新版本中包含的候选者:

  • 箭头功能
  • 增强的对象文字
  • 解构赋值
  • 默认、剩余和扩展参数
  • 统一码
  • 可子类化的内置函数
  • 承诺
  • 代理
  • MathNumberStringObjectAPI
  • 反射API

其余功能涉及更多,并且可能需要更长的时间来实现。虽然在 JDK 9 更新版本中包含其中一些内容可能是可行的,但我们目前的目标是将它们用于未来的主要 JDK 版本。这些功能是:

  • 课程
  • 发电机
  • 模块
  • 模块加载器
  • 尾部调用

尽管实现了 ES6 功能,JDK 9 Nashorn 存储库中的 Nashorn 解析器已经支持 ES6 语法更改。

备择方案

我们可以选择暂时忽略 ECMAScript 6,而不是这里提出的迭代方法,而是专注于改进现有的基于 ECMAScript 5 的实现。

或者,我们可以尝试一次性实现 ES6。然而,这会阻止我们尽早获得反馈并发现错误。此外,ES6 中新功能的大小和数量使得这种方法不切实际

不对 ES6 做出任何努力将是一个错误,并向用户和客户传递错误的信息。

测试

作为实现 ES6 部分工作的一部分,我们开发了功能测试的基础主体,它将成为 JEP 的一部分。

官方 ECMAScript 一致性测试套件test262的 ES6 版本的运行工作也已开始。初步结果令人鼓舞。然而,从 ES5.1 版本的 test262 切换到 ES6 版本作为我们的主要测试套件是不可行的,因为许多测试需要完整的 ES6 实现。

在这个 JEP 的开发和集成过程中,我们将依赖 ES6 版本的 test262 来发现错误并填补缺失的部分。我们的计划是,一旦我们实现完整的 ES6 功能,就切换到 ES6 版本作为我们的主要 ES6 测试套件。

风险和假设

ECMAScript 6 规范已经发布,其中大部分已在各种 JavaScript 引擎中实现,因此不再存在移动规范或规范文本中含糊不清的风险。

我们对功能的优先级划分可能会遗漏开发人员需要的某些功能。然而,所提出的迭代方法可以确保随着时间的推移提供所有缺失的功能。

依赖关系

ES6 中的各种功能之间存在依赖性,我们选择的实现顺序是按照复杂性递增的顺序来解决这些功能的。