Javascript: Модульний шаблон проти шаблону конструктора / прототипу?


77

Я хотів би знати, чи шаблон модуля або шаблон конструктора / прототипу більш застосовний до моєї роботи.

В основному я використовую ненав’язливий javascript - документ HTML має посилання на файл .js.

Я розумію шаблон модуля:

  • викликати метод INIT (що в основному є загальнодоступним методом, який я можу створити та повернути за допомогою шаблону модуля)
  • У методі INIT призначте всі події кліків тощо.

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

Я розумію шаблон конструктора / прототипу:

  • для створення об'єктів
  • для використання успадкування (тобто підтипів супертипу)

Чи правильно я вважаю, що для надання ненав’язливого javascript шаблон модуля ідеально підходить?

Відповіді:


70

Конструктор-функції та прототипи є одним із розумних способів реалізації класів та екземплярів. Вони не зовсім відповідають цій моделі, тому вам зазвичай потрібно вибрати певну схему або допоміжний метод для реалізації класів з точки зору прототипів. ( Деякі передумови щодо занять у JS .)

Шаблон модуля, як правило, використовується для простору імен, де у вас буде один екземпляр, який виконує функцію сховища для групування пов'язаних функцій та об'єктів. Це інший випадок використання, ніж те, що корисно для прототипування. Вони насправді не змагаються між собою; ви можете із задоволенням використовувати обидва разом (наприклад, помістити конструктор-функцію всередину модуля і сказати new MyNamespace.MyModule.MyClass(arguments)).


1
тому в моєму випадку я не дуже хочу створювати екземпляри, тому шаблон модуля, мабуть, ідеально підходить для того, що я хочу. Коли ви говорите простір імен .. Як мені створити простір імен у шаблоні модуля? Я бачив один спосіб використання YUI - але чи справді це потрібно?
Мартін

16
Особливої ​​хитрості немає, ви просто використовуєте JavaScript Objectяк пошук. Або створіть літерал об’єкта безпосередньо, як var MyModule= { someProperty: 3, someFunction: function() { ... }, somethingElse: null };або призначити MyModule.someFunction= function() { ... };. Якщо ви хочете приватні змінні, ви робите це у негайно викликаному вираженні функції і маєте цей returnоб'єкт у закритті ... особисто я вважаю, що "справжні" приватні змінні є цілковитою втратою часу.
bobince

1
Думка про те, що js має класи, може ввести в оману - це відмінна книга на тему Ви не знаєте JS | Прототипи This & Object - незважаючи на той факт, що ES6 має підтримку "класів", це здебільшого лише маска над прототиповою функціональністю, і мислення цих класів у тому сенсі, як ви думаєте про класи в Java або C #, призведе вас шлях до плутанини. При використанні прототипу я пропоную шаблон OOLO, як описано в гл6 вищезгаданої книги.
Йорданія

1
Я б також припустив, що ідея успадкування в js є дещо помилковою, і делегування є кращим терміном: chipersoft.com/p/inheritance . Я погоджуюсь, що шаблон модуля корисний для акуратного відокремлення складних додатків, але існує безліч хороших випадків використання шаблону модуля для складання / доповнення, особливо якщо ви працюєте з розробниками, які не настільки знайомі з js - їм, швидше за все щоб зрозуміти , що таке IIFE це проти (дійсно) розуміння прототипу: adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
Jordan

5
@bobince Я знаю, що ти давно це публікував, але чому ти вважаєш реальні приватні змінні марною тратою часу?
PDN

13

Шаблон модуля набагато простіший та елегантніший, ніж прототип. Однак, спочатку думаючи про мобільність. Це не є відповідним шаблоном для середніх / великих об’єктів, оскільки для ініціалізації потрібно проаналізувати весь блок перед початком. Багаторазові закриття також створюють кругові залежності, які збирач сміття не звільняє (особливо IE), це призводить до збільшення розміру пам'яті, що не звільняється до закриття вікна (або вкладки) - перевірте chrome task manager для порівняння - Час завантаження зворотне пропорційно розміру об'єкта за допомогою шаблону модуля, хоча це не так для прототипного успадкування. Викладені вище заяви перевіряються за допомогою кількох контрольних показників, подібних до цього: http://jsperf.com/prototypal-performance/54

Як видно з останнього тесту. Маленькі об’єкти краще ініціалізувати як звичайний об’єкт (без цих зразків). Він підходить для одиночних об'єктів, які не потребують ні закриття, ні успадкування. Доцільно оцінити, чи взагалі вам потрібні ці закономірності.


4

Шаблон прототипу допомагає нам розширити функціональність, і в пам'яті є лише один екземпляр функцій, незалежно від кількості об’єктів. У шаблоні модулів кожен об'єкт створює новий екземпляр функцій в пам'яті, але він надає концепцію приватних / загальнодоступних змінних та допомагає інкапсулювати змінні та функції.


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