Шаблон модуля JavaScript з прикладом [закрито]


136

Я не можу знайти жодних доступних прикладів, що показують, як два (або більше) різних модулів з'єднані для спільної роботи.

Отже, я хотів би запитати, чи не встигає хтось написати приклад із поясненням того, як модулі працюють разом.


Це все змінилося за останні чотири роки, але завдяки ревній надмірній поміркованості ця застаріла інформація буде навішуватись назавжди . Ось сторінка MDN про модулі ES6.
bbsimonbb

Відповіді:


256

Для того, щоб підходити до схеми модульного дизайну, вам потрібно спочатку розібратися в цих поняттях:

Вираз функцій негайного виклику (IIFE):

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

Існує два способи використання функцій. 1. Оголошення функції 2. Вираз функції.

Тут використовується вираження функції.

Що таке простір імен? Тепер, якщо ми додамо простір імен до вищевказаного фрагмента коду

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

Що таке закриття в JS?

Це означає, що якщо ми оголосимо будь-яку функцію з будь-якою змінною сферою / всередині іншої функції (в 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 для наведеного вище коду.

Мета - приховати змінну доступність від зовнішнього світу.

Сподіваюся, це допомагає. Щасти.


було б краще назвати iife? для смислових цілей та кращого відстеження стека? це змінило б щось у коді?
Jeroen

2
Ваш перший приклад (function() { /* Your code goes here */}());насправді IIFE (Відразу Виклик функції Expression), добре це неназваний СОГ не має імені , так що ви навіть можете назвати це IIAFE (Відразу Виклик функції Anonymous Expression) докладніше про IIFE на stackoverflow.com/questions/ 2421911 /…
Adrien Be

для чого використовується оператор повернення? якщо ми пропустимо повернення {}, тоді функція додавання та скидання буде публічною, і я думаю, вони можуть отримати доступ до локальної змінної суми? маю рацію?
Mou

ваш другий приклад схожий на предмет або я не прав?
Причина

4
Це не стосується питання ОП. Це опис шаблону модуля, а не приклад того, як кілька модулів можуть працювати разом, як хотіла ОП.
Ерік Траутман

39

Я б дуже рекомендував усім, хто зайнявся цим предметом, прочитати безкоштовну книгу Адді Османі:

"Вивчення шаблонів дизайну JavaScript".

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

Ця книга мені надзвичайно допомогла, коли я починав писати більш доступний JavaScript, і я все ще використовую його як довідник. Погляньте на його реалізацію різних моделей, він дуже добре їх пояснює.


Я також рекомендую прочитати мою статтю про "остаточну схему
tfmontague

1
Як це порівнюється з "
Шаблонами

4
Книга Стояна набагато вичерпніша. Він охоплює більше, ніж просто моделі високого рівня, але також більш детально розповідає про інші найкращі практики Спільного Впровадження.
Code Novitiate

1
відгуки про "Навчання шаблонів дизайну JavaScript" amazon.com/product-reviews/1449331815
Adrien Be

3
відгуки про "Шаблони JavaScript" Стояна Стефанова amazon.com/product-reviews/0596806752 . Примітка: які здаються набагато кращими, ніж ті, які виходять із "Навчання шаблонів дизайну JavaScript"
Adrien Be

19

Я подумав, що розширюся на вищезгадану відповідь, поговоривши про те, як ви вбудовуєте модулі разом у додаток. Я читав про це в книзі Doug Crockford, але, будучи новим у JavaScript, все це було ще трохи загадково.

Я походжу з фону ac #, тому там я додав термінологію, яку я вважаю корисною.

Html

У вас буде html-файл kindof верхнього рівня. Це допомагає мислити це як файл вашого проекту. Кожен файл 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/


Усі реалізації AMD також забезпечують попередню компіляцію в один файл.
I-Lin Kuo

1
Це правильно, але отриманий оптимізований файл потребує бібліотеці завантажувача (просто перевірив його за допомогою r.js v2.1.14), що зазвичай є досить вагомим. Як тільки ми склали код, нам не потрібно розв’язувати асинхронно завантажені залежності, нам ця бібліотека не потрібна. Поміркуйте лише: ми загортаємо модулі в AMD, це означає асинхронізацію. завантаження, потім компілюйте їх в єдиний файл (більше немає окремого завантаження), але завантажте всю бібліотеку, щоб вирішити їх (що тепер зайве). Це не звучить як оптимальний спосіб для мене. Чому взагалі AMD, коли ми не завантажуємо асинхронно?
Дмитро Шейко

almond.js забезпечує менший ваговий навантажувач для готового виробничого коду, ніж RequireJS, але порівняно кажучи, перевага від продуктивності від створення лише одного запиту http значно перевищує вартість додавання коду навантажувача до модуля, тому, хоча це менш оптимально, це у значно менших масштабах. Питання, на мою думку, повинно бути розгорнутим - чому припускати синхронність, коли браузер не є? Я насправді вважаю, що і в RequireJS, і у CommonJS повинні бути вбудовані обіцянки.
I-Lin Kuo

Обидва формати є дійсними шляхами до CommonJS Modules / 2.0 та забезпечують однакову масштабованість. Як на мене - працювати з модулями CJS / 1.1 (саме так я маю на увазі під CommonJS) набагато простіше, код виглядає чистіше.
Дмитро Шейко

Я зустрів такі переваги AMD, як: * може завантажувати більше, ніж просто файли JavaScript; * псевдоніми шляху; Ну, CommonJS Compiler вирішує це - він завантажує не-JavaScipt / JSON залежності як дані і може бути забезпечений конфігурацією збірки (включаючи псевдоніми). Єдиний недолік, який вимагає будівництва. Але сьогодні все одно будують проект для попередніх процесорів CSS. Тож мова йде лише про додавання додаткового завдання для Grunt / Gulp ...
Дмитро Шейко

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.