polyfill和transpiler有什么区别?

Roh*_*rma 27 javascript

polyfill和transpiler有什么区别?

我经常阅读类似语境中使用的相同术语.

Sir*_*rko 27

这两种方法都有相同的用途:您可以编写使用某些功能的代码,这些功能尚未在目标环境中实现.然而,他们通过使用不同的技术来做到这一点.

一个填充工具将试图仿效某些API,因此可以使用它们,就好像他们已经实现.

一个transpiler,另一方面将改变你的代码和其它代码,这已经可以执行替换相应的代码段.

通常,如果目标浏览器尚未实现要使用的最新前沿功能(读取浏览器API),则使用polyfill.另一方面,转换器将允许您使用语言功能,目标环境尚不支持,例如一些ES6功能,如胖箭头功能.


Sin*_*tfi 17

填充工具

这个词polyfill是一个发明的术语(由Remy Sharp提出),用于指定一个较新的特征并生成一段代码,该代码等同于行为,但能够运行older JS environments.

例如:

ES1定义一个方法,isNaN(value)用于确定值是否为非法数字(非数字).

ECMAScript 1是NaN方法

ES6定义一个被调用的方法Number.isNaN(value)也确定一个值是否为NaN(非数字).

ECMAScript 6是NaN方法

如果您注意到,Number.isNaN()并不是每个浏览器都支持,那么为此您可以填充该方法.并非所有新功能都是完全可填充的.有时,大多数行为都可以进行多层填充,但仍然存在小的偏差.您应该非常,非常小心地自己实施polyfill,以确保您尽可能严格遵守规范.或者更好的是,使用一套已经过审查的可以信任的polyfill,例如由ES5-Shimand 提供的那些ES6-Shim.

// These method is a sample of making polyfill 
if (!Number.isNaN) {
    Number.isNaN = function isNaN(x) {
        return x !== x;
    };
}
Run Code Online (Sandbox Code Playgroud)

Transpile

没有办法填充已添加到该语言的新语法.新语法会将旧JS引擎中的错误抛出为无法识别/无效. 因此,更好的选择是使用一种工具将您的新代码转换为旧代码.这个过程通常被称为 "转换"一个术语transforming + compiling.

您应该关注以下几个重要原因transpiling:

  1. The new syntax added to the language is designed to make your code more readable and maintainable.较旧的等价物往往更复杂.您应该更喜欢编写更新更清晰的语法,不仅适用于您自己,也适用于开发团队的所有其他成员.
  2. If you transpile only for older browsers, but serve the new syntax to the newest browsers,您可以使用新语法来利用浏览器性能优化.这也让浏览器制造商拥有更多真实的代码来测试他们的实现和优化.
  3. Using the new syntax earlier allows it to be tested more robustly in the real world,它向Javascript委员会(TC39)提供早期反馈.如果早期发现问题,可以在语言设计错误成为永久性之前更改/修复问题.

有很多很棒transpilers的选择.在撰写本文时,这里有一些很好的选择:

  1. 巴别塔(原为6to5):Transpiles ES6 and above into ES5
  2. Traceur:Transpiles ES6, ES7, and beyond into ES5

  • 啊,您忘了添加这个很棒的解释的某些部分的源代码。https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#old--new (3认同)

eha*_*hab 7

pollyfill 和 transpilation 都允许您在旧环境(例如旧浏览器与新浏览器)中使用新功能,主要区别在于 pollyfill 通过在旧环境本身中实现该功能来实现这一点。因此,如果我们使用 Es6 Es5 术语,polyfill 使您能够通过在 Es5 中实现新功能来使用它,但是某些新功能永远无法在 Es5 中实现,例如考虑一下 Es6 引入的箭头语法,这就是转译的地方需要。

因此,需要转译的一个例子是箭头语法 (() => {}),因为你永远无法在 es5 中实现它,而可以使用 pollyfil 的一个例子是,如果你想实现 Array.prototype.includes方法,你可以像这样轻松实现它

// taken from mdn
if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    'use strict';

    if (search instanceof RegExp) {
      throw TypeError('first argument must not be a RegExp');
    } 
    if (start === undefined) { start = 0; }
    return this.indexOf(search, start) !== -1;
  };
}
Run Code Online (Sandbox Code Playgroud)

现在这里有一些主要区别:

  • pollyfill 将使用本机功能(如果存在),但转译则不会。由此得出的结论是,出于安全和性能方面的原因,Polyfills 应该优于转译。
  • Transpilation 与语言语法有关,而 pollyfill 与语言语法和本机浏览器 API(或其他环境 API)有关。
  • 转译是在编译时进行的,而 pollyfill 是在运行时进行的,这就是两者之间的区别。