Объяснение определения библиотеки RequireJS - PullRequest
48 голосов
/ 02 декабря 2011

Я начал читать несколько уроков о RequireJS. Ни в одном из них не было удовлетворительно объяснено ключевое слово «определение». Может ли кто-нибудь помочь мне со следующим:

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

Что такое "определить"? Определить функцию с массивом и анонимной функцией внутри него? Или что-то еще? Может кто-нибудь дать мне больше информации об этом виде определений?

Дополнение: Спасибо nnnnnn и pradeek за ваши ответы. Здесь, в Европе, было 2:30 ночи, когда я писал вопрос. Возможно, поэтому я не узнал, что это был простой вызов функции.

Ответы [ 4 ]

61 голосов
/ 03 декабря 2011

define не является специфическим для RequireJS, оно является частью спецификации AMD . Берк заметит, что RequireJS не реализует в точности то, как AMD это определяет, поскольку AMD на самом деле не учитывала браузеры.

define не имеет анонимной функции. define - это метод, доступный для файлов JavaScript на базе AMD для загрузки их данных. Такие библиотеки, как RequireJS, делают это доступным для вас. Конкретная реализация, вероятно, не имеет значения для вас. Поэтому я перейду к тому, что вы указали, так как это наиболее распространенный способ объявления модуля.

define( [array], object );

Массив - это список модулей, от которых зависит этот модуль. Между модулями и файлами существует отношение 1 к 1. Вы не можете иметь несколько модулей в файле или несколько файлов для одного модуля.

Объект - это модуль, который вы определяете. Это может быть что угодно, структура или функция, которая возвращает структуру. Прочитайте документы по RequireJS для получения более подробной информации.

Если объект является функцией, аргументы, переданные функции, являются модулями, перечисленными как зависимости в первом определяемом аргументе. Также важно отметить, что когда вы передаете функцию как object, она запускается только один раз. К методам или свойствам, созданным в этом одном экземпляре, можно получить доступ в любое время, однако затем к ним могут обращаться другие модули, которые перечисляют этот модуль как зависимость.

Удачи, я рекомендую поиграть с этим и читать документы, когда вещи не имеют смысла. Документы RequireJS отлично подходят для быстрого начала работы модулей AMD.

5 голосов
/ 11 ноября 2013

Я нашел define, определенный в нижней части файла require.js (мне тоже было интересно, что это за слово define, и вот ответ I ):

/**
 * 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 голос
/ 28 августа 2013

Я нашел эту страницу Почему AMD? очень полезно. Подводя итог, можно сказать, что спецификация AMD полезна в преодолении проблемы «написать несколько тегов сценария с неявными зависимостями, которые необходимо вручную упорядочить». Это полезно при загрузке зависимостей перед выполнением необходимых функций, аналогично import в других языках программирования, таких как python. AMD также предотвращает проблему загрязнения глобального пространства имен. Проверьте "It is an improvement over the web's current "globals and script tags" because" раздел.

0 голосов
/ 16 июня 2015

Я думаю, что спецификация RequireJs API довольно хорошо подводит итог:

Если модуль имеет зависимости, первый аргумент должен быть массивом имен зависимостей, а второйАргумент должен быть функцией определения.Функция будет вызываться для определения модуля после загрузки всех зависимостей.Функция должна возвращать объект, который определяет модуль.

В них перечислены примеры всех различных синтаксических форм определений.

...