【问题标题】:Trying to understand what this JS function does and what its parameters are, can someone explain?试图了解这个 JS 函数的作用以及它的参数是什么,有人可以解释一下吗?
【发布时间】:2019-04-13 20:47:03
【问题描述】:

我正在阅读我最近下载的库中的一些代码,以便为 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)

什么是工厂参数/功能,导出来自哪里?有人可以逐步指导我了解此功能的作用吗?

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

【问题讨论】:

  • 这是UMD 样式模块的初始化

标签: javascript closures amd commonjs


【解决方案1】:

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

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

以下部分检查您使用的环境是节点、amd 还是常规JS,以便他们将在每个环境要求中定义模块,即node 只需要您设置exports 对象,@ 987654336@ 需要您使用define 函数,而在原版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 中,您不需要命名导出,因为您只需要该文件,即 const glMatrix = require("./common.js");,但在 JS 中,您需要从全局对象中检索,这就是为什么它只是需要的一个命名为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();

【讨论】:

  • 那么如果不需要输入名称,node和amd如何决定模块的名称呢?
【解决方案2】:

什么是出厂参数/功能

它是函数的第二个参数……它的开头定义在您包含的代码的最后一行。剩下的你砍掉。

出口从何而来

当你调用它时。这里:factory(global.glMatrix = {})

【讨论】:

  • 是的,但您可能想要解决代码的意图或提供这样做的参考。当然,这不是一件简单的事情,因为 UMD 模式有许多官方变体。然而,这也是它很重要的原因,因为在某些环境中出现故障的手动调整版本并不罕见。
猜你喜欢
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 2012-07-27
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多