RequireJS库定义的解释

54

我开始阅读了几篇有关RequireJS的教程。在这些教程中,没有一个能够让我满意地解释"define"关键字。请问有人可以帮助我吗:

define(
  ["Models/Person", "Utils/random", "jquery"], 
  function (Person, randomUtility, $) {..}
)  

"define"是什么?它是一个带有数组和匿名函数的函数吗?还是其他什么东西?有人能给我更多关于这种定义的信息吗?

补充:感谢nnnnnn和pradeek的回答。当我发布问题时,在欧洲这里已经是凌晨2:30了。也许因此我没有意识到它只是一个简单的函数调用。

4个回答

63

define并不是RequireJS特有的,它是AMD规范的一部分。但实际上AMD并没有考虑浏览器环境,因此RequireJS的实现和AMD的规定略有不同。

define本身并没有匿名函数。它是一个方法,可用于加载基于AMD的JavaScript文件中的数据。像RequireJS这样的库使其对您可用。具体的实现方式可能对您没什么价值。因此,我将讨论您提供的那种声明模块的方式,因为这是声明模块最常见的方法。

define( [array], object );

Array是该模块所依赖的其他模块的列表。每个模块与一个文件相对应。您不能在一个文件中拥有多个模块,也不能有多个文件对应于一个模块。

Object是您要定义的模块。这可以是任何东西,一个结构体,或者一个返回结构体的函数。查阅RequireJS文档以获取更多详细信息。

如果Object是一个函数,则传递给该函数的参数是第一个define参数中列出的依赖项模块。还需要注意的是,当您将函数作为object传递时,它只会运行一次。在这个唯一的实例化上创建的方法或属性可以随时访问,并且可以被列出该模块为依赖项的其他模块所访问。

祝你好运,我建议在遇到困惑的时候去尝试实践并阅读文档。RequireJS文档是快速入门AMD模块如何工作的好资源。


5

我在 require.js 的底部找到了 define 的定义(我也在想这个单词 define 是什么东西,这就是我所寻找的答案):

/**
 * The function that handles definitions of modules. Differs from
 * require() in that a string for the module should be the first argument,
 * and the function to execute after dependencies are loaded should
 * return a value to define the module corresponding to the first argument's
 * name.
 */
define = function (name, deps, callback) {
    var node, context;

    //Allow for anonymous modules
    if (typeof name !== 'string') {
        //Adjust args appropriately
        callback = deps;
        deps = name;
        name = null;
    }

    //This module may not have dependencies
    if (!isArray(deps)) {
        callback = deps;
        deps = null;
    }

    //If no name, and callback is a function, then figure out if it a
    //CommonJS thing with dependencies.
    if (!deps && isFunction(callback)) {
        deps = [];
        //Remove comments from the callback string,
        //look for require calls, and pull them into the dependencies,
        //but only if there are function args.
        if (callback.length) {
            callback
                .toString()
                .replace(commentRegExp, '')
                .replace(cjsRequireRegExp, function (match, dep) {
                    deps.push(dep);
                });

            //May be a CommonJS thing even without require calls, but still
            //could use exports, and module. Avoid doing exports and module
            //work though if it just needs require.
            //REQUIRES the function to expect the CommonJS variables in the
            //order listed below.
            deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
        }
    }

    //If in IE 6-8 and hit an anonymous define() call, do the interactive
    //work.
    if (useInteractive) {
        node = currentlyAddingScript || getInteractiveScript();
        if (node) {
            if (!name) {
                name = node.getAttribute('data-requiremodule');
            }
            context = contexts[node.getAttribute('data-requirecontext')];
        }
    }

    //Always save off evaluating the def call until the script onload handler.
    //This allows multiple modules to be in a file without prematurely
    //tracing dependencies, and allows for anonymous module support,
    //where the module name is not known until the script onload event
    //occurs. If no context, use the global queue, and get it processed
    //in the onscript load callback.
    (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
};

1
我发现这个页面 为什么选择 AMD? 非常有帮助。总结一下,AMD规范有助于克服“编写大量脚本标签与隐式依赖项并手动排序”的问题。类似于其他编程语言(如Python)中的import,它有助于在执行所需函数之前加载依赖项。 AMD还可以防止全局命名空间污染问题。请查看 “它是对Web当前的“全局变量和脚本标记”的改进,因为”部分。

0

我认为RequireJs API specification已经很好地总结了:

如果模块有依赖项,则第一个参数应该是一个依赖项名称的数组,第二个参数应该是一个定义函数。一旦所有依赖项都加载完毕,该函数将被调用以定义模块。该函数应返回一个定义模块的对象。

他们列出了所有不同语法形式的定义示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接