EcmaScript-6向后兼容性

14
我很好奇理解/弄清楚 ECMAScript-6 的新更改是否能在旧浏览器上运行。
我之所以问这个问题是因为:我还记得在 ECMAScript-5 中引入了"use strict",它的目的是为了与旧版本兼容。
这意味着旧浏览器将继续正常工作,并且当它们在解析新的 JavaScript 代码时遇到"use strict"语句时,它们会忽略它。
而新的 JS 引擎会将"use strict"语句视为一些特殊方式进行处理,详见严格模式

因此,谈到这个问题

我非常怀疑并且好奇当ECMAScript-5兼容的浏览器解析ECMAScript-6代码时会发生什么。

我的怀疑是因为ECMAScript-6的新功能涉及语法更改/更新。而那些不了解新语法的旧浏览器将在遇到以下任何新语法时开始抛出错误:

yield[*]、Map、Set、WeakMap、function* foo(){}、=>、for...of等

我的担忧是ECMAScript-6中新功能的决定/包含是否考虑了支持旧浏览器而不会破坏代码?

如果是,那么如何做到的?

如果不是,那么我应该怎么做才能让我的旧浏览器用户满意?

我看到一个解决方案可以让使用旧版浏览器的用户满意,那就是在我的项目中包含一些像转译器这样的工具,比如traceur-compiler。这将把我的ECMAScript-6代码转换为ECMAScript-5等效代码。但是,我还有其他方法可以让我的旧版浏览器用户满意吗?

1
许多ES6功能不向后兼容,只能在ES6 JS引擎中运行。如果您的代码在浏览器中运行,它将仅在最新的浏览器中工作,或者您必须等待您的整个浏览器支持基础升级到ES6(从现在起数年)。如果您的代码在像node.js这样的东西中运行,或者如果它是特定版本特定浏览器的插件,则可以更好地控制JS引擎,并且可能更早地使用ES6功能。"use strict";的不同目的更符合向后兼容性。 - jfriend00
这很遗憾,但似乎是真的 :( 你也可以将评论发布为答案... - dopeddude
Map、Set 和 WeakMap 可以进行 polyfill,如果您可以避免使用新语法,es6 代码将在 es5 上运行... - dandavis
1
另外,您应该知道,在旧引擎上使'use strict';语法无错误所需的努力是不必要的,因为它只是字符串声明,无论如何都不会破坏任何流程... - binariedMe
"use strict"并不能神奇地使ES5特性在ES4浏览器中可用,就像"<! DOCTYPE html>"并不能神奇地使HTML5特性在HTML4浏览器中可用。你自己负责使你的代码和网站向后兼容。 - Sheepy
你需要插入一个转译器,使你的代码兼容旧版本浏览器。 - Shami Qureshi
2个回答

9
你试图解释的是向前兼容性。显然,ES5(或者更准确地说是ES5引擎)没有向前兼容性。无论如何,这很难实现并且很少见。
尽管你可以看到即将推出的ES7的一些功能已经发布,因此可能会考虑实现ES6引擎来考虑这些增强功能。因此,当ES7推出时,某些功能将在旧引擎中工作。 回答问题,ES6是否向后兼容的答案将是“是”。是的!ES6的引擎将很高兴运行ES5的代码,但反过来则不成立。

8
许多ES6功能在ES5 JS引擎中无法工作,特别是新的语法功能,如for/of或箭头函数、生成器等。一些功能,如Set对象,可以部分地为旧浏览器提供Polyfill,而其他功能则无法实现。
在您的问题列表中,有以下功能:
yield[*], Map, Set, WeakMap, function* foo(){}, =>, for...of

这些都不兼容旧版本的Javascript,会导致语法或引用错误。一些MapSet的特性可以进行polyfill(但不是全部)。Yield、generators、箭头函数和for...of只是新的语法,旧浏览器无法处理并且不能执行。可以使用ES6转译器将代码转换为ES5兼容代码。这不是真正的ES6向后兼容,而是使用仅使用ES5语法来实现与新的ES6语法相同的事情的代码转换。其中一些是通过polyfills完成的,另一些则是使用仅使用ES5代码(通常更多的ES5代码)来表达ES6构造的替代方式完成的。

如果您的代码在类似node.js的东西中运行,或者它是特定浏览器特定版本的插件,则可以更好地控制JS引擎,并且可能比在浏览器中更早地使用ES6功能。

如果您的代码在浏览器中运行,并且您没有使用转译器将其转换为ES5代码,则需要很长时间(多年)才能使大多数在互联网上使用的浏览器都准备好ES6。

"use strict";的不同目的(消除对不良做法的支持)更符合允许与旧版本的兼容性,而不是像生成器这样的新语言功能,因为"use strict";构造是专门选择成为新浏览器可以检测到的东西,但旧浏览器只会看到它作为一个普通字符串。表示新语言语法的新ES6功能并不是这种方式,因为旧的浏览器不知道如何处理它们,即使它们可以以某种方式忽略较新的语法,它们也不支持新语法所意味着的功能。
您可能会发现本文有用,其中讨论了在尝试使用ES6时遇到的一些问题: ECMAScript 6 Resources For The Curious JavaScripter 如果您想在各种浏览器中使用大多数ES6功能,则最好的选择可能是使用类似BabelJS的工具进行代码转换。这将把您的ES6代码转换为ES5兼容的代码,在任何ES5浏览器中运行。您可以使用ES6编写代码,但代码将在各种浏览器中运行。

或者,如果你只在特定的环境中运行(比如一个特定版本的浏览器插件)或者一个特定的运行时引擎,比如node.js,那么你可以编写使用ES6功能的代码,这些功能已经被该特定引擎支持。


5
这个答案非常误导,因为它错误地使用了“向后兼容”的术语。 - ben
@ben - 请描述一下你认为这个术语的使用不正确的地方。我很乐意改进答案,但还不太明白你的意思。 - jfriend00
2
当然。请查看WIKI中“向后兼容”的定义:https://en.wikipedia.org/wiki/Backward_compatibility ES6是完全向后兼容的,即任何ES5程序在ES6上运行,因为ES6是ES5的超集(据我所知)。 - ben
1
@ben - 是原帖作者以那种方式使用了该术语。我只是回答原帖作者所问的问题。我已从回答中完全删除了该术语,只是谈论与旧版JS引擎的兼容性。你可以从原帖作者问题的第一行清楚地看出他们的意图和我的回答。 - jfriend00
2
仅仅因为提问者使用了一个术语错误,并不意味着回答也应该如此...在纠正后现在已经点赞了。 - ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接