【问题标题】:ES6 (ECMAScript 2015) support as of 2018自 2018 年起支持 ES6(ECMAScript 2015)
【发布时间】:2018-06-29 21:49:10
【问题描述】:

作为一名刚接触 JavaScript 编程的资深程序员,尽管阅读了很多文章,但我仍然有以下问题尚不清楚。

对于以下代码,

class Animal {
    constructor(public name) { }
    move(meters) {
        console.log(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    move() {
        console.log("Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    move() {
        console.log("Galloping...");
        super.move(45);
    }

var sam = new Snake("Sammy the Python")
var tom: Animal = new Horse("Tommy the Palomino")

sam.move()
tom.move(34)

是否需要将其转译成与 ES5 兼容的形式才能与 Node.js 一起运行?

最后,我可以尝试使用上面的 TypeScript/ES6 代码玩的任何在线网站吗?

  • 我将它复制到我的 chrome 控制台,并收到一个我不明白的错误 - Unexpected strict mode reserved word,并且
  • 我在http://www.typescriptlang.org/play/index.html 上尝试过,但console 的输出在那里不起作用。

请帮忙。谢谢。

【问题讨论】:

  • 所有浏览器不使用V8引擎
  • 你的 Snake 类中有一堆语法错误。
  • 为了增加获得答案的机会,请提出 1 个问题,而不是 5 个问题。
  • "supported" 在 node.js ES6 图表中意味着您可以在没有转译器的情况下使用本机 ES6 功能。你可以用 Javascript 编写那个 ES6 特性,它就可以工作。
  • TypeScript 必须转译成 Javascript,因为没有浏览器或 node.js 引擎直接运行 TypeScript。当你转译你的 TypeScript 时,你可以选择你想要它生成的目标 Javascript 是什么(ES5 或 ES6)。

标签: javascript node.js typescript


【解决方案1】:

看浏览器对 ES6 (ECMAScript 2015) 的支持,可以看出支持水平远不如 Node.js,所以问题来了,

许多不同的浏览器和其中的许多不同的 Javascript 引擎,每个都有自己的 ES6 支持级别。最新版本的 node.js 通常在 V8 引擎支持的内容上是最新的。许多浏览器的发布周期较长,可能不是最新的,但每个浏览器都不同,并且有自己的发布策略和 ES6 支持级别。

如果 Node.js 和浏览器都使用现代 V8 引擎,为什么支持水平如此不同?

如果您将最新版本的 node.js 与 Windows 上的最新版本的 Chrome 进行比较,您不会发现在支持方面有太大差异。您正在查看的 ES6 支持图表对我来说似乎很旧。例如,Chrome 长期以来一直支持 Set 对象,但您的图表显示 false

查看 Node.js 中对 ES6 的支持,我发现现在确实很少有 ES6 功能不受支持。但是,图表中支持的具体含义是什么?即,

支持意味着您可以直接使用该功能而无需转译器,但准确度取决于声明它的文档的来源。一些文档对给定功能的所有各种边缘情况进行了广泛的测试。 其他人只是寻找一般实施。因此,例如,如果您正在查看对 Set 对象的支持并且它说“支持”,那么这意味着您可以只编写使用 Set 对象的普通 Javascript,它就可以工作。该文档的准确性取决于他们的数据来源和测试的彻底性。

是否意味着即使我使用支持 ES6 功能编写,我仍然需要使用 Babel 编译器将 ES6 代码编译为 ES5 供 Node.js 使用?

没有。在支持 ES6 中给定功能的 Javascript 引擎中,您可以为该功能编写 ES6 代码并直接在该 Javascript 引擎中运行它。不需要转译。

对于为 Node.js 运行的 TypeScript ES6 风格的 JavaScript 代码,尽管 Node.js 几乎涵盖了所有 ES6 功能,但它们仍然需要转译成与 ES5 兼容的形式,对吧?即,

您展示的类定义是纯 ES6 代码。这些将在支持 ES6 的 Javascript 引擎中正常工作。

如果您编写 Typescript 代码,那么您将不得不将 TypeScript 转换为 Javascript,因为没有 Javascript 引擎(我知道)直接支持 TypeScript。在将 TypeScript 转译为 Javascript 时,您通常可以指定是希望转译器生成 ES5 兼容代码(将在 ES5 引擎或 ES6 引擎中运行)还是 ES6 兼容代码(仅在 ES6 引擎中运行),具体取决于您的目标环境能够做什么。

是否需要转译成与 ES5 兼容的形式才能与 Node.js 一起运行?

您的特定代码似乎包含至少一个需要转换的 TypeScript 样式变量声明。其余的看起来像普通的 ES6 Javascript,它可以在任何 ES6 引擎中工作而无需转译。

当我删除 TypeScript 时,修复代码中的一些语法错误并正确实现 Animal 构造函数,然后此代码在 node.js v8.8.1(我目前已安装)和 Chrome 63.0 中运行良好.3239.132、Edge 41.16299.15.0 和 Firefox 57.0.4 都在 Windows 10 上:

    // Generic ES6 code

    class Animal {
        constructor(name) { 
            this.name = name;
        }
        move(meters) {
            console.log(this.name + " moved " + meters + "m.");
        }
    }
    
    class Snake extends Animal {
        move() {
            console.log("Slithering...");
            super.move(5);
        }
    }
    
    class Horse extends Animal {
        move() {
            console.log("Galloping...");
            super.move(45);
        }
    }
    
    var sam = new Snake("Sammy the Python");
    var tom = new Horse("Tommy the Palomino");
    
    sam.move();
    tom.move(34);

您可以在任何您希望查看结果的浏览器中自己运行这个 sn-p(假设浏览器足够现代以支持堆栈溢出片段)。它适用于我拥有的所有当前版本的浏览器,除了 IE 11.192.16299.0(IE 不支持 ES6 不足为奇)。

我将它复制到我的 chrome 控制台,并收到一个我不理解的错误 - Unexpected strict mode reserved word,

当我尝试在 node.js 中运行您的代码时,这发生在我身上,直到我从中删除了 TypeScript,以便它只是普通的 ES6。我认为这个特定的错误是由这一行中的public 引起的:

constructor(public name) { }

因为这不是 ES6 规范的一部分(它显然是 TypeScript 的一部分)。

您似乎很想问一个问题,但还没有明确表达出来:“您如何知道是否必须进行转译?”。

答案是您必须了解您希望在其中运行的目标环境与您计划使用的最新功能之间的交叉。如果您正在编写仅在 node.js 中运行的服务器端代码,那么它会简单得多。检查一个综合表格,例如http://node.green/,研究它对您计划使用的 node.js 版本和相关功能的说明。如果它表明您应该能够使用该功能,则使用该功能编写代码,为它编写一个测试用例并验证您编写的代码和您正在使用的功能是否都能正常工作。将其添加到您的知识体系中,了解您可以在该版本的 node.js 中使用什么和不能使用什么。然后,您可以假设 node.js 的所有未来版本也将支持该功能。

如果您正在编写代码以在浏览器中运行,那么生活会复杂得多。如果您计划支持很多浏览器并且真的不想担心 ES6 支持,那么只需转换为 ES5 目标并继续您的业务。

如果您想使用非转译代码,那么您需要在很多浏览器中进行大量测试。您必须首先准确指定您将支持哪些浏览器的版本,然后您必须编写代码和测试用例,并且您必须在您计划支持的每个浏览器中进行测试。真的没有捷径。当您发现某些东西不起作用时,您将不得不寻找 polyfill 或变通方法,或者停止使用该 ES6 功能。

【讨论】:

  • "似乎有一个问题你很想问,但还没有准确地表达出来",天哪,是的!谢谢!!
【解决方案2】:

在将要使用代码的环境中测试代码。使用可用的方法在您使用代码的环境中实施特定的标准或规范。或者尝试自己创建一种方法来解决您在代码开发过程中遇到的问题,同时注意其他人能够从自己的角度解决和解决问题、错误或要求的进展和持续存在的问题。

仅仅由于文档声明浏览器已实现规范或标准这一事实并不意味着该实现与该规范一致,或完全实现。验证浏览器是否实现标准的唯一方法是自己使用代码进行测试。提交问题并尝试自己修复错误。

浏览器使用不同的引擎,包括GeckoWebKit,而不是单独使用V8;并且可以随着时间的推移在规范的名称和实现方面发生变化;见Monitor and potentially deprecate support for multitrack SourceBuffer support of 'sequence' AppendModeHow to use "segments" mode at SourceBuffer of MediaSource to render same result at Chomium, Chorme and Firefox?。有很多浏览器。例如,Lynx 不使用 V8。

web platform tests

web-platform-tests 项目是 W3C 协调的尝试,旨在构建一个 Web 平台堆栈的跨浏览器测试套件。在 a 中编写测试 允许它们在所有浏览器中运行的方式提供了浏览器项目 相信他们正在交付与兼容的软件 其他实现,以及以后的实现将是 与他们的实现兼容。这反过来又给了 Web 作者/开发人员相信他们实际上可以依赖 Web 平台以兑现跨浏览器工作的承诺 设备不需要额外的抽象层来覆盖 规范编辑者和实施者留下的空白。

例如,对Web Speech API 的一项测试,其中volume 属性被指定为能够设置,但在设置volume 属性时无法检测到Chromium 或Firefox 的音频输出变化SpeechSynthesisUtterance 指定范围内的不同值。

规范与实际浏览器实现完全不同。规范或标准可以并且在实际浏览器实现之前编写好(如果有的话)。您可以使用browserify,或者自己编写代码以在浏览器中使用 NodeJS 模块或其他非原生代码。

【讨论】:

    猜你喜欢
    • 2020-12-20
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    相关资源
    最近更新 更多