Мне любопытно, есть ли какие-либо передовые практики, связанные с JQuery при создании инкапсулированных блоков кода.
Обычно, когда я создаю страницу, мне нравится инкапсулировать функции, используемые на этой странице, внутри объекта. Это позволяет мне некоторую инкапсуляцию при создании приложений. Нет ничего, что я ненавижу больше, чем просмотр файла JavaScript с кучей этих
function doSomethingOnlyRelevantOnThisPage() {
// do some stuff
}
Это создает беспорядочный дизайн и не очень хорошо инкапсулирует функциональность.
Обычно во многих фреймворках существует стандарт, который используется для выполнения этой инкапсуляции.
В Mootools они отдают предпочтение буквальному обозначению объекта:
var Site = {
// properties and methods
}
В YUI они отдают предпочтение нотации Self Executing Function:
(function() { // properties and methods })()
Во втором примере хорошо то, что создается замыкание, что позволяет вам определять частные свойства и методы.
У меня такой вопрос: есть ли у поклонников JQuery какие-нибудь передовые методы создания этих чисто инкапсулированных структур? В чем причина их использования?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Обычно я следую шаблону прототипа:
MyFunction = function(param1, param2)
{
this.property1 = param1;
// etc.
}
MyFunction.prototype =
{
memberOne: function(param1)
{
// ...
},
memberTwo: function(param2)
{
}
}
Вы получаете нечто вроде «конструктора» (самой функции) и инкапсулированных «методов» и «полей».
Это проще для тех, кто привык к объектно-ориентированным языкам на основе классов :)
Верно, верно ... в этом случае я бы предпочел самоисполняющиеся анонимные функции.
Я использую YUI и jQuery при разработке (виджеты YUI и несколько удобных функций, селекторы jQuery и «расширения» javascript), а общий шаблон javascript, который я использую, таков:
/*global YAHOO, $ */
// Create the public-scope accessable namespace for this page
YAHOO.namespace('Project');
YAHOO.Project.page = function() {
// Private members
var self = {};
// Public members
var pub = {};
pub.init = function() {
};
return pub;
} ();
// When the DOM is loaded, initialize this module
$(document).ready(YAHOO.Project.page.init);
Теперь ясно, что вы можете удалить вызов YAHOO.namespace (), если не хотите использовать YUI, но это основная схема. Он использует буквальную нотацию объекта, но также позволяет определять частные свойства и методы.
Просто помните, что при вызове закрытых членов или обращении к закрытым переменным нужно ссылаться на них как на self.funcName(). Вы можете определить их вне объекта self, но тогда вы получите несоответствие повсюду в вашем объекте, где вы пытаетесь выяснить, является ли size_of() частным методом или определен глобально где-то еще.
Поскольку я уже некоторое время работаю с jQuery, я выбрал стандартный шаблон, который мне подходит.
Это комбинация шаблона модуля YUI с добавлением небольшого количества шаблона плагина jQuery.. В итоге мы использовали самоисполняющийся шаблон закрытия. Это полезно по нескольким причинам:
Вот как это выглядит:
;(function($) {
var myPrivateFunction = function() {
};
var init = function() {
myPrivateFunction();
};
$(init);
})(jQuery);
Мы поняли, что присвоение результата выполнения функции, подобное шаблону модуля YUI, раскрывает код, который потенциально может быть вызван из кода представления. Мы хотим предотвратить это, поэтому этот шаблон подходит.
Конечно, мы могли бы написать встроенный метод init, не определяя переменную для функции. Мы согласились с тем, что явное определение функции init сделало код более понятным для читателей.
Что произойдет, если мы захотим разделить функции между страницами / внешними файлами js? Мы просто подключаемся к существующему механизму, который jQuery предоставляет для расширения самого объекта jQuery - функции расширения.
Если функции статические, мы используем $ .extend, а если они работают с обернутым набором, мы используем функцию $ .fn.extend.
Надеюсь, это кому-то поможет.
Я продолжаю видеть этот шаблон, но мне не терпится привести более полный пример - у меня есть страница с несколькими отдельными и довольно сложными интерактивными элементами, логика которых должна быть инкапсулирована отдельно друг от друга. Есть ли предложения по организации кода в такой ситуации? Использование $ .fn.extend для каждой отдельной части пользовательского интерфейса кажется нелогичным.
Я определенно не буду защищать использование расширения функции jquery, если вы не пишете плагин - то есть что-то, что можно повторно использовать на многих страницах. В вашем случае я бы разбил свою функциональность на отдельные части, создав самовыполняющуюся функцию, содержащую эту логику в ее собственном закрытии. Затем любой общий код можно прикрепить к самому jQuery через $ .extend, что позволит вам иметь вспомогательные функции, которые не требуют контекста элемента для работы.
Очень хорошая статья о выражении мгновенно вызываемой функции (IIFE) benalman.com/news/2010/11/…
Но это полезно только в том случае, если вы планируете инкапсулировать состояние в объектах. Вам нужно будет вызвать new для этих объектов, чтобы создать экземпляры. В моем случае они будут вести себя больше как статический класс с точки зрения объектно-ориентированного программирования.