我想通过js从useragent获取浏览器版本和操作系统 - 这是一个实践示例(原因是 - 我知道 - 功能检测是你如何正确地做到这一点;)。
我偶然发现了一个这样做的小图书馆,现在我试图了解最新情况。
请参阅此Codepen:http://codepen.io/anon/pen/gPWZGE?editors=001
显然,通过运行!function (name, definition) {
var module;
var define;
if (typeof module != 'undefined' && module.exports) module.exports = definition();
else if (typeof define == 'function' && define.amd) define(definition);
else this[name] = definition();
}
- 您可以获得从浏览器useragent中提取的版本。但是函数 bowser 本身是一个匿名函数 - 即使我可以访问此函数中与这部分代码有关的元素
{{1}}
说实话,我几乎不知道那里有什么 - 有人可以解释这些线路在做什么吗?
非常感谢
答案 0 :(得分:2)
好的,一步一步......
首先你有一个IIFE
!function( name, definition ) {
// some code
}( 'bowser', function(){
// your module code
});
这会立即使用两个参数调用第一个函数:模块的名称(此处为“bowser”)和实际的定义函数。在该定义函数中,您可以创建模块:您可以定义任何对象,属性以及它需要工作的任何其他内容。重要的一点是:您的界面(模块上的“外部”视图,必须由该定义函数返回(在您的代码中,这是第282行:return bowser;
)。
外部函数然后确定如何发布您的模块:
首先,它寻找CommonJS环境:
typeof module != 'undefined' && module.exports
这将用于例如NodeJS内部。如果找到了相应的对象,它会将您的模块导出为CommonJS模块:module.exports = definition()
。
如果这不是CommonJS环境,那么脚本看起来是不是AMD(例如,requireJS):
typeof define == 'function' && define.amd
同样,如果匹配,模块将导出为AMD模块:define(definition)
。
最后,如果这既不是CommonJS也不是AMD,脚本假定它是一个(vanilla)浏览器或类似的东西,只是将模块附加到全局命名空间:
this[name] = definition();
注意,每次调用定义函数并将返回值导出为模块。这就是定义函数必须返回模块接口的原因。