2013-07-21 3 views
118

Я не могу найти доступных примеров, показывающих, как два (или более) разных модуля подключаются для совместной работы.Шаблон модуля JavaScript с примером

Итак, я хотел бы спросить, есть ли у кого есть время, чтобы написать пример, объясняющий, как модули работают вместе.

+0

Это все изменилось в течение последних четырех лет, но благодаря ревностным чрезмерной сдержанности, это устарелый информация будет висеть вокруг * навсегда *. Вот [страница MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) в модулях ES6. – bbsimonbb

ответ

237

Для того, чтобы приблизиться к Modular шаблону дизайна, вы должны понимать эти концепции первыми:

Сразу-Вызванная Функция Выражения (IIFE):

(function() { 
     // Your code goes here 
}()); 

Есть два способа, которые можно использовать функции , 1. Объявление функции 2. Определение функции. Здесь используется выражение определения функции.

Что такое пространство имен? Теперь, если мы добавим пространства имен к выше кусок кода, то

var anoyn = (function() { 
}()); 

Что такое замыкание в JS?

Это означает, что мы объявляем какую-либо функцию с любой переменной scope/внутри другой функции (в JS мы можем объявить функцию внутри другой функции!), Тогда она будет считать эту область функций всегда. Это означает, что любая переменная во внешней функции будет всегда читаться. Он не будет читать глобальную переменную (если она есть) с тем же именем. Это также является одной из целей использования модульного шаблона проектирования, исключающего конфликт имен.

var scope = "I am global"; 
function whatismyscope() { 
    var scope = "I am just a local"; 
    function func() {return scope;} 
    return func; 
} 
whatismyscope()() 

Теперь мы применим эти три понятия я уже упоминал выше, чтобы определить наш первый модульный дизайн шаблона:

var modularpattern = (function() { 
    // your module code goes here 
    var sum = 0 ; 

    return { 
     add:function() { 
      sum = sum + 1; 
      return sum; 
     }, 
     reset:function() { 
      return sum = 0;  
     } 
    } 
}()); 
alert(modularpattern.add()); // alerts: 1 
alert(modularpattern.add()); // alerts: 2 
alert(modularpattern.reset()); // alerts: 0 

jsfiddle for the code above.

Цель состоит в том, чтобы скрыть переменной доступности от внешнего мира.

Надеюсь, это поможет. Удачи.

+0

было бы лучше назвать iife? для семантических целей и лучшего отслеживания стека? изменилось бы что-нибудь в коде? – Jeroen

+2

Ваш первый пример '(function() {/ * Ваш код идет здесь * /}());' на самом деле является IIFE (Немедленно вызывать выражение функции), нормально, это анонимно, потому что у него нет имени, поэтому вы даже можете позвонить это IIAFE (немедленное обращение к анонимному выражению функции), см. больше на IIFE на http://stackoverflow.com/questions/2421911/what-is-the-purpose-of-wrapping-whole-javascript-files-in-anonymous-functions -li/26738969 # 26738969 –

+0

Почему используется оператор return? если мы опустим return {}, функция добавления и сброса будет общедоступной, и я думаю, что они могут получить доступ к локальной сумме переменных? я прав? – Mou

36

Я очень рекомендую любой, кто зайдет на эту тему читать бесплатно книгу Адди Османи в:

«Обучение JavaScript Design Patterns».

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Эта книга помогла мне безмерно, когда я начинал в написании более ремонтопригодны JavaScript, и я до сих пор использовать его в качестве ссылки. Взгляните на его различные варианты модульных шаблонов, он объясняет их очень хорошо.

+0

Я бы также рекомендовал прочитать мою статью на «Окончательном шаблоне модуля», который не описан в книге Адди Османи: https://github.com/tfmontague/definitive-module-pattern – tfmontague

+0

Как это сравнить с «Шаблоны JavaScript» »Стояном Стефановым – JohnMerlino

+3

Книга Стояна гораздо более полная. Он охватывает не только шаблоны высокого уровня, но и более подробно рассказывает о других практиках JS. –

16

Я думал, что я расскажу о том, как вы поместили модули вместе в приложение. Я читал об этом в книге doug crockford, но, будучи новичком в javascript, все это было немного загадочно.

Я родом из C# фона, поэтому добавил терминологию, которую я нахожу полезной.

Html

Вы будете иметь некоторый kindof HTML-файл верхнего уровня. Это помогает думать об этом как о файле проекта.Каждый файл javascript, который вы добавляете в проект, хочет пойти на это, к сожалению, вы не получаете поддержку инструмента для этого (я использую IDEA).

Вам нужно добавить файлы в проект с подлинника тегами, как это:

 <script type="text/javascript" src="app/native/MasterFile.js" /></script> 
     <script type="text/javascript" src="app/native/SomeComponent.js" /></script> 

Оказывается рушится теги вызывает вещи на провал - в то время как это выглядит, как XML, это действительно что-то с сумасшедшими правилами!

пространство имен файлов

MasterFile.js

myAppNamespace = {}; 

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

Модуль (ы)

SomeComponent.js

myAppNamespace.messageCounter= (function(){ 

    var privateState = 0; 

    var incrementCount = function() { 
     privateState += 1; 
    }; 

    return function (message) { 
     incrementCount(); 
     //TODO something with the message! 
    } 
})(); 

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

Концепции

Я думаю, что это помогает думать о верхней строке в SomeComponent как пространство имен, где вы объявляете что-то. Единственное предостережение в этом - все ваши пространства имен должны сначала появиться в каком-то другом файле - это всего лишь объекты, внедренные нашей переменной приложения.

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

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

6

Здесь https://toddmotto.com/mastering-the-module-pattern вы можете найти шаблон, подробно объясненный. Я бы добавил, что второе, что касается модульного JavaScript, - это структурирование вашего кода в нескольких файлах. Многие люди могут посоветовать вам здесь пойти с AMD, но я могу с уверенностью сказать, что в какой-то момент вы столкнетесь с медленным ответом на страницу из-за многочисленных запросов HTTP. Выход - предварительная компиляция ваших модулей JavaScript (по одному на файл) в один файл, следующий по стандарту CommonJS. Посмотрите на образцы здесь http://dsheiko.github.io/cjsc/

+0

Все реализации AMD также обеспечивают предварительную компиляцию в один файл. –

+1

Это правильно, но в результирующем оптимизированном файле требуется библиотека загрузчика (просто переустановила ее с помощью r.js v2.1.14), что обычно довольно весомо. Как только мы скомпилировали код, нам не нужно решать асинхронно загруженные зависимости, нам не нужна эта библиотека. Просто подумайте: мы переносим модули в AMD, это означает асинхронный. загрузите, затем скомпилируйте их в один файл (без отдельной загрузки больше), но загрузите всю библиотеку, чтобы обратиться к ним (что теперь избыточно). Это не звучит как оптимальный способ для меня. Почему AMD вообще, когда мы не загружаем асинхронно? –

+0

almond.js обеспечивает меньший весовой загрузчик для готового кода производства, чем RequireJS, но сравнительно говоря, преимущество в производительности, заключающееся в том, что он не делает только один HTTP-запрос, намного превышает стоимость добавления кода загрузчика в модуль, поэтому, хотя он менее оптимален, это в гораздо меньших масштабах. Вопрос, на мой взгляд, должен быть обернут - зачем предполагать синхронность, когда браузер не работает? Я на самом деле считаю, что как RequireJS, так и CommonJS должны иметь встроенную реализацию обещаний. –

Смежные вопросы