Я создал следующие три модуля. Вопрос в том, чтобы с помощью IIFE (без использования модульной библиотеки, такой как common.js, require.js и т. Д.) Спроектировать это так, чтобы только module2 был видимым для module3, и только module1 должен быть видимым для module2.

Q2 . Как избежать того, чтобы module1 и module2 входили в глобальную область видимости, так как мне нужно выставить ТОЛЬКО mondule3, который будет доступен из html?

Module1.js

var module1 = (function(){
  var  module1Msg = "This is Module 1";

  return {
    module1Msg:module1Msg
  };
})();

Module2.js

var module2 = (function(){
  var  module2Msg = module1.module1Msg +" - "+" This is Module 2";

  return {
        module2Msg:module2Msg
  };
})();

Module3.js

var module3 = (function(){
  var  module3Msg = module2.module2Msg +" - " +" This is Module 3";

  return {
    module3Msg:module3Msg
  };
})();

И используя эти модули из следующего файла HTML

<html>
<head>
<title>Module Experiment</title>
<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="module3.js"></script>

<script>
    alert(module3.module3Msg);

</script>
</head>
<body>
<div id="display"></div>

</body>
</html>
-1
ATHER 17 Дек 2015 в 22:22

3 ответа

Лучший ответ

Ну, вы можете загрузить модуль самостоятельно. Вы можете использовать загрузку модуля, создав функцию, которая загружает файлы javascript для вас, у вас больше не будет тегов сценария внутри html (кроме вашего начального приложения).

Например, вы можете сделать что-то подобное:

<html>
<head>
<title>Module Experiment</title>
<script>
    'use strict';
    var scriptBase = './js/';
    var scriptcounter = 0;

    function require(arr, callback) {
        var requested = 0, loaded = 0;
        arr.forEach(function(script) {
            var scriptTag = document.createElement('script');
            scriptTag.id = 'myscript' + (++scriptcounter);
            requested++;
            scriptTag.addEventListener('load', function() {
                loaded++;
                if (loaded === requested) {
                    callback();
                }
            });
            scriptTag.src = scriptBase + script + '.js';
            document.head.appendChild(scriptTag);
        });
    }

    window.addEventListener('load', function() {
        require(['module1'], function() {
            require(['module2'], function() {
                require(['module3'], function() {
                    // everything loaded
                    console.log('I can call module3 here');
                    var el = document.getElementById('display');
                    el.innerHTML = module3.module3Msg;
                });
            });
        });
    });
</script>
</head>
<body>
<div id="display"></div>

</body>
</html>

В этом случае require принимает массив и вызывает обратный вызов при загрузке скрипта. В то же время вы можете запустить свой код или выбрать другой файл для выполнения дополнительной работы.

Функцию также можно вызывать как require(['module1', 'module2', 'module3'], function() { ... }), но у вас может быть проблема с тем, что module2 загружается до module1, что может привести к ошибке отсутствующей ссылки, поэтому я написал код require Выше в 3 разных заявлениях требуют. (это все еще может быть в ваших текущих настройках. Неясно, какой сценарий будет получен в сети в первый раз, поэтому ваше приложение может работать на 90% и давать некоторые трудные для воспроизведения ошибки, остальные 10%.

Вы могли бы упростить это самостоятельно, хотя бы «определив» свои модули в общем классе, а затем внедрив некоторые классы на основе их строкового идентификатора, но я думаю, это выходит за рамки вашего вопроса.

1
Icepickle 17 Дек 2015 в 19:52

Ты не можешь Шаблон, который вы используете, требует, чтобы каждый модуль помещал в глобальную область все, что он хочет, чтобы он был доступен из другого модуля.

Раскрывающийся шаблон модуля позволяет вам ограничить переменную, чтобы она была доступна только для самого модуля. Это не позволяет вам ограничивать переменные другими конкретными модулями.


Вы можете ограничить модуль, поместив его полное определение в () в конце другого модуля (и записав его в качестве аргумента), но тогда вы не сможете хранить их в отдельных файлах.

0
Quentin 17 Дек 2015 в 19:32

Просто передайте ссылку на модуль в качестве параметра для конкретного файла. Передайте module2 в module3 в качестве параметра и сделайте то же самое с module1 и module2

-1
Maksim 17 Дек 2015 в 19:26