首页 > 解决方案 > 试图了解这个 JS 函数的作用以及它的参数是什么,有人可以解释一下吗?

问题描述

我正在阅读我最近下载的库中的一些代码,以便为 WebGL 做矩阵数学。但是,我很难理解这个函数的作用。这来自 glMatrix.js 库。

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = global || self, factory(global.glMatrix = {}));
}(this, function (exports)

什么是工厂参数/功能,出口从何而来?有人可以逐步引导我了解此功能的作用吗?

编辑:这只是代码的第一部分,这就是左括号永远不会关闭的原因。

标签: javascriptclosuresamdcommonjs

解决方案


这是一种称为UMD的设计模式,它是IIFE设计模式的更高级版本。它们都包装了您的代码,创建了一个新的私有范围。两者之间的主要区别在于UMD更抽象,并且也可以在浏览器中工作,node.jsamd不仅仅是浏览器。

您在问题中显示的第一行和最后一行基本上是IIFE部分(减去结尾,因为您已经裁剪了它)。您正在调用iife并传递globalakawindow对象和factory函数,您只能function (exports)在代码中看到该部分。

以下部分检查您使用的环境是节点、amd 还是常规环境,JS以便他们将在每个环境中定义模块,即node只需要您设置exports对象,amd需要您使用该define功能,在 vanilla 中JS您只需添加反对windowglobal反对。

typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.glMatrix = {}));

在 node 和 amd 中,您不需要命名您的导出,因为您只需要该文件 ie const glMatrix = require("./common.js");,但在 JS 中您需要从全局对象中检索,这就是为什么它只是一个需要命名的 ie factory(global.glMatrix = {})。该行将glMatrix属性添加到全局对象(最初作为空对象),然后将其作为参数传递给您的factory函数,该函数附加了您应该能够从范围外访问的所有函数、值和类。

UMD模式的实现可能因库而异。例如,这是一种无需将任何参数传递给IIFE

(function() {
  var global = this;

  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = global || self, factory(global.foo = {}));

  function factory(exports) {
    exports.bar = function() {
      console.log("Hello World!");
    };
  }
})();

foo.bar();

在节点中,您可以创建一个新文件并导出您想要的任何内容。然后,Node 会将这些导出与文件相关联,而不是与属性相关联(这在浏览器 JS 中会发生)。例如,一个文件名为foo.js以下内​​容:

function bar() {
    console.log("Hello World!");
}

exports.bar = bar;

可以像这样从另一个文件访问:

const foo = require("foo.js");
foo.bar();

或者您可以使用Destructuring直接访问属性:

const { bar } = require("foo.js");
bar();

推荐阅读