由于我对 RequireJS 和 Node.js(以及一般的 JavaScript)的了解有限,我通常会查看一些著名的 JavaScript 库的源代码。每次我看到这样的东西:
( // Wrapping
function (root, factory) {
if (typeof exports === 'object') { // Node.js
var underscore = require('underscore');
var backbone = require('backbone');
module.exports = factory(underscore, backbone);
} else if (typeof define === 'function' && define.amd) { // Require.JS
define(['underscore', 'backbone'], factory);
}
}(this, function (_, Backbone) { // Factory function, the implementation
"option strict";
function Foo() {}
return Foo; // Export the constructor
})
); // Wrapping
我能理解的(希望如此):
- 当脚本未包含在
<script>
中时,包装代码的匿名函数将自动执行。标签 - 此代码适用于 RequireJS 和 Node.js(
if
在最开始检查);factory
的结果功能要么分配给module.exports
(Node.js) 或用作define
的参数函数(RequireJS)。
Q1:这段代码在没有 RequireJS 和 Node.js 的情况下如何工作? if
和 else if
检查会失败,factory
函数永远不会执行,脚本不返回任何内容。
Q2:传递this
的目的是什么?作为root
争论?没用过
最佳答案
实际上,我认为您问题中截取的代码不适用于浏览器全局变量。此片段中使用的模式称为 UMD - 通用模块定义。事实上,这种模式有很多变体,您可以在 https://github.com/umdjs/umd 上浏览更多示例
至于问题:
第一季度 这段代码无法在没有 RequireJS 或任何其他 AMD 加载器的浏览器中运行,原因很明显——只有两个检查——用于 NodeJS 和 define 函数,所以如果不使用 AMD 库,工厂函数将不会被调用。
要调用工厂函数,只需为浏览器全局变量添加另一个条件
if (typeof exports === 'object') { // Node.js
var underscore = require('underscore');
var backbone = require('backbone');
module.exports = factory(underscore, backbone);
} else if (typeof define === 'function' && define.amd) { // Require.JS
define(['underscore', 'backbone'], factory);
} else {
// Browser globals
factory(root._, root.Backbone);
}
请注意,我们使用传递给包装函数的根对象作为 nekman指出在浏览器环境中它会被设置为window
,所以我们只是将定义在该窗口上的全局对象传递给工厂,这些对象通常由其他script
标签定义页。希望这能回答您的第二个问题。
关于javascript - 为什么这段 JavaScript 代码(RequireJS 和 Node.js 的模块模式)有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14781224/