gre*_*emo 5 javascript module function node.js requirejs
由于我对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
Run Code Online (Sandbox Code Playgroud)
我能理解的(希望如此):
<script>标记中时,将自动执行包装代码的匿名函数if最开始检查); factory函数的结果既可以分配给module.exports(Node.js),也可以用作函数的define参数(RequireJS).Q1:没有RequireJS和Node.js,这段代码如何工作?if并且else if检查将失败,factory函数永远不会执行,脚本将返回nothig.
Q2:this作为root论点传递的目的是什么?它从未使用过
实际上我认为你的问题中剪切的代码不适用于浏览器全局变量.此剪辑中使用的模式称为UMD - 通用模块定义.事实上,这种模式有很多种,你可以在https://github.com/umdjs/umd上浏览更多的例子.
至于问题:
Q1 这个片段在没有RequireJS或任何其他AMD加载器的浏览器中不起作用,原因显而易见 - 只有两个检查 - 用于NodeJS和定义功能,所以不使用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);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们使用传递给包装函数的根对象,并且nekman指出它将window在浏览器环境中设置,因此我们只是将在该窗口上定义的全局对象传递给工厂,这些对象通常由script页面上的其他标记定义.希望这能回答你的第二个问题.