📜  JavaScript |填充和转译

📅  最后修改于: 2022-05-13 01:58:10.474000             🧑  作者: Mango

JavaScript |填充和转译

由于 JavaScript 版本的快速变化,语法形式和词汇也在 JavaScript 中更新,因此可以看出许多 JavaScript 功能是新添加的,可能不一定在旧浏览器中可用,即在旧版本的浏览器上运行的浏览器JavaScript。另一个问题是,一些浏览器不认为 JavaScript 的最新功能是安全的,因为它能够显示出强大的功能,因此它们没有被包括在内或作为实验模式被包含在内,以限制使用。但是我们为什么还要讨论这个呢? JavaScript 主要用于开发客户端应用程序,程序的成功执行部分取决于客户端的机器,即客户端浏览器上可用的 JavaScript 版本。

现在天真的方法是只运行那些可以在客户端浏览器中运行的功能,尽管这确实不是一种健康的方法。开发人员可以使用两种主要技术将 JavaScript 的新功能“引入”旧版浏览器,即PolyfillingTranspiling

填充

Polyfilling 是 Remy Sharp 发明的术语。它是可以用作一种向后兼容性度量的方法之一。这个定义最好由雷米本人给出。

如果我们说明他的意思,我们会知道 polyfill 或 polyfiller 是一个代码段,它的行为应该与 JavaScript 的新特性相同,并且仍然能够在旧版本上运行。例如,ES2015 提供了一个新的实用程序 Number.isNaN(...) 来提供一种安全且准确的方法来检查NaNNot a Number 值。我们可以使用 polyfilling 来复制这种行为,并在那些 ES2015 之前的浏览器上使用它。以下代码段将对我们的案例有所帮助。

// Check if Number.isNaN already exists.
// If False then proceed.
if (!Number.isNaN) {
  
    // Define explicitly for older browsers.
    Number.isNaN = function isNaN(x) {
  
        // This is a property of NaN.
        // No two NaN can be equal to the other.
        // Because NaN is a concept not a comparable value.
        return x !== x;
    };
}

我们首先检查该方法是否已经可用,如果是,则阻止定义显式版本。如果不存在,那么我们肯定是在较旧版本的 JavaScript 上,因此我们使用 NaN 的属性明确定义一个,即没有两个 NaN 彼此相等,因为 NaN 是一个概念,而不是一个可比较的值来与另一个相等。因此,如果它们不相等,则返回 True,否则返回 False。这可以被认为是最简单的 polyfill 之一。

注意:所有新功能都不是可填充的,或者不可能总是创建没有任何偏差的填充,因此在明确实施填充时,建议了解整体工作。但是,许多开发人员更喜欢使用已经可用的 polyfill。其中一些在下面提到。

  • ES6 垫片
  • ES5 垫片

转译

新的 JavaScript 版本也带来了语法更新,这是不可能的,因为它根本不会被执行,而是会在旧的 JavaScript 引擎中抛出语法错误,这就是转译器发挥作用的地方。它的名字来源于它执行Transformation + Compiling的两个操作的联合。接下来,我们现在可以将“Transpiler”定义为将具有新语法的代码转换为旧代码等效项的工具,这个过程称为“Transpiling”。

通过开发实践,在使用 Transpiling 时,必须编写代码以保持新语法,但在部署项目时使用类似于 minifier 或 linter 的 transpiler 来部署已转译的旧语法友好程序。这就提出了一个问题,为什么我们还要费心用新的语法形式编写,同时仍然部署旧的?这是一个非常合乎逻辑的问题,并且有很多好点可以作为答案给出,其中很少给出以下答案。

  • 不用说,新的语法被添加到语言中以使代码更易读和更易于维护,即新版本比旧版本更好。因此建议
    编写更新和更清晰的语法以获得更好的结果。
  • 仅为旧浏览器转译,同时为更新的浏览器提供更新的语法,我们可以获得浏览器性能优化的优势。
  • 较早地使用较新的语法可以在现实世界中对其进行更稳健的测试,从而提供较早的反馈,如果足够早地发现,可以在这些语言设计错误成为永久性错误之前对其进行更改/修复。因此,从长远来看,使用较新的语法会使语法更加可靠。

让我们举一些 Transpiling 的例子。 ES2015 新增了默认参数值的语法特性,可以使用以下方式实现。

// Default Parameter Value Example.
// If no parameter is passed a will be 5.
function myFunc(a = 5)
{
    console.log(a);
}
  
myFunc(96); // Logs 96.
myFunc(); // Logs 5 as default.

如您所见,如果未提供参数,我们会考虑默认参数值,但此语法在 ES2015 之前的引擎中将无法识别。因此,在转译之后,我们将得到如下的旧等价物。

// Default Parameter Value Example.
// If no parameter is passed a will be 5.
function myFunc()
{
    // Using Ternary Operator to assign default
    // 5 if undefined.
    var a = (arguments[0] !== undefined) ? arguments[0] : 5;
    console.log(a);
}
  
myFunc(96); // Logs 96.
myFunc(); // Logs 5 as default.

如上例所示,如果发现参数未定义,我们可以使用三元运算符分配默认值,这将产生与 ES6 等效的结果相似的结果。下一个例子让我们看看 ES6 的粗箭头方法。

// Function Defining is now this easy.
var myFunc = () => {
    console.log("This is a function.");
}
  
myFunc(); // This is a function.

正如您在上面的示例中看到的那样,我们甚至可以在不使用关键字函数的情况下定义一个函数,并且也不妨碍可读性,但这在 ES6 之前的引擎中不会被识别,因此等效代码如下所示。

// Function Defining is now this easy.
var myFunc = function() {
    console.log("This is a function.");
}
  
myFunc(); // This is a function.

在了解了 Transpilers 之后,如果不了解一些可用的最强大的 Transpilers 就结束本文会很奇怪。以下是此类工具的一小部分。

  • 通天塔
  • 示踪剂

希望我们已经涵盖了足够多的知识,以了解这些方法是什么,以及为什么使用它们不仅对开发人员很重要,而且对 JavaScript 本身的开发也很重要。

参考
https://remysharp.com/2010/10/08/what-is-a-polyfill