以下两种建立依赖关系的方法有什么区别,它们似乎达到了完全相同的结果。对我来说,使用#1管理依赖项更容易:
//#1
define(function (require) {
var $ = require('jquery');
//$ is available here
});
//#2
define(['jquery'],function ($) {
//$ is available here
});
使用#1是否有任何不利之处。我在构建包含它在一个文件中的依赖项的模块时遇到了一些困难。使用#1可以做任何事吗?
答案 0 :(得分:2)
这两种配方达到了相同的效果。在内部,RequireJS将第一个公式转换为:
define(['jquery'], function (require) {
var $ = require('jquery');
//$ is available here
});
它使用单个字符串参数扫描函数以查询require
,收集所有参数并将它们添加到传递给define
的依赖项列表中。因此,由于两个原因,它比第二种配方的计算成本更高。首先,RequireJS必须使用正则表达式来扫描函数并找到对require
的调用。其次,当你加载这样的多个模块时,必须多次调用require
。比较依赖于4个其他模块的模块,并在转换后使用var x = require('x')
加载它们:
define(['a', 'b', 'c', 'd'], function (require) {
var a = require('a');
var b = require('b');
var c = require('c');
var d = require('d');
// Actual work.
});
和这样写的模块相同:
define(['a', 'b', 'c', 'd'], function (a, b, c, d) {
// Actual work.
});
在进入实际工作部分之前,第一个模块需要调用require
四次。我不会因为性能上的差异而失眠,但它确实存在。
Jeremy指出了第一个公式的限制,但文档中elsewhere,James Burke(RequireJS的作者)对这个可能的问题给出了更详细的意见:
并非所有浏览器都提供可用的Function.prototype.toString()结果。截至2011年10月,PS 3和较旧的Opera Mobile浏览器没有。 这些浏览器更可能需要针对网络/设备限制优化模块的构建,所以只需使用知道如何将这些文件转换为规范化依赖关系数组形式的优化器进行构建,例如RequireJS优化器。
由于无法支持此toString()扫描的浏览器数量非常少,可以安全地为所有模块使用这些加糖表单,特别是如果您想要排列依赖项名称使用将保存其模块值的变量。
(强调补充。)
有人会想到"哦不!我要拥有来使用优化器"看不到大局。有可能toString()
不可用的平台无论如何都需要进行优化。
并解决您的具体问题:
使用#1可以做任何事吗?
使用#1中的语法糖本身并不会使优化器无法优化您的代码。我有一个> 50模块项目,混合了两种风格。我没有做任何特别的事情让r.js
工作。
答案 1 :(得分:0)
以下文件:
http://requirejs.org/docs/api.html#funcmodule
解释了第一种格式的最大问题 - 它依赖于Function::prototype::toString
并非100%可靠。
编辑
来自文档:
此包装器依赖于Function.prototype.toString()来提供函数内容的有用字符串值。这在某些设备上不起作用,如PS3和一些较旧的Opera移动浏览器。使用优化器提取数组格式的依赖项,以便在这些设备上使用。