Как вы пишите свои библиотеки?
Наверное каждый когда-либо писал свою библиотеку всяких нужных и не очень функций. Я изучаю js, поэтому тоже вот потихоньку пишу всякие плюшки и чета их стало много. Решил оформить все в виде библиотеки, чтобы не захламлять глобальное пространство. Выглядит это так:
var GLIB = (function(){ var $G = {}; $G.scroll = function(){ /*****/ }; $G.serialize = function(){ /*****/ }; // и т.д. и т.п... return $G; }()); Однако теперь столкнулся с проблемой захламления пространства самой библиотеки. Ну к примеру написал я некий модуль, который делает ajax запросы. У него есть настройки по дефолту, функция установки настроек, непосредственно функция отправки запросов и т.д... То есть модуль состоит из нескольких функций: var GLIB = (function(){ var $G = {}; /*** Ajax ***/ $G.ajax = function(){/* делает запросы и выполняет заданные функции */}; $G.ajaxSetup = function(){/* установка глобальных опций */}; $G.ajaxSetting = {/* дефолтные настройки */}; /*** Other ***/ $G.scroll = function(){/*****/}; $G.serialize = function(){/*****/}; // и т.д. и т.п... return $G; }()); Проблема в том, что в составе модуля не все функции должны быть расшарены наружу. Например объект $G.setting не должен быть доступен для прямой записи в него. Значит что? значит нужно // вместо $G.ajaxSetting = {}; //сделать var ajaxSetting = {}; Все, наружу эта переменная не доступна, но она теперь захламляет пространство внутри библиотеки... Короче я уже не знаю, как лучше оформить свою библиотеку, чтобы и имена переменных были короткие, и чтобы потом не было конфликтов внутри. |
PS да и к тому же навеное в своей библиотеке нужно отделить функции-одиночки от модулей, которые могут использовать эти самые функции-одиночки, чтобы потом можно было безболезненно выкидывать лишние модули
|
Ну, например, можно продолжать развивать в том же духе:) :
var GLIB = (function(){ var $G = {}; /*** Ajax ***/ $G.ajax = (function(){ var ajaxSetting = {/* дефолтные настройки */}; var ajax = function(){/* делает запросы и выполняет заданные функции */}; ajax.setup = function(){/* установка глобальных опций */}; return ajax }()); /*** Other ***/ $G.scroll = function(){/*****/}; $G.serialize = function(){/*****/}; // и т.д. и т.п... return $G; }()); |
Hapson, если есть модули и зависимости между ними, стоит прочитать, например, эту статью.
|
Sweet,
Сейчас почитаю. Немного не так, зависимостей между модулями нет. Есть ряд функций, входящих в состав библиотеки, которые абсолютно независимы. То есть примитивные функции - поиск значения или ключа в массиве/объекте, применение функции ко всем значениям массива, trim и подобные. А есть модули, которые мало того что состоят из нескольких функций, так они еще используют примитивные функции библиотеки. То есть библиотека делится на две части: обязательные функции и модули. Обязательные выкидывать нельзя, модули можно |
Aetae,
Ну да, что-то я об этом не подумал. Библиотека в библиотеке. Типа так: var GLIB = (function(){ var $G = {}; /*** Ajax ***/ $G.ajax = (function(){ var __setup = function(set){ set = typeof set == "object" ? set : {}; this.type = set.type || "GET"; this.url = set.url || window.location.href; this.param = set.param || null; this.async = typeof set.async == "undefined" ? true : set.async === false ? false : true; this.contentType = set.contentType || "application/x-www-form-urlencoded"; this.timeout = set.timeout || 3000; this.error = set.error || function(){}; this.success = set.success || function(){}; this.beforeSend = set.beforeSend || function(){}; this.afterSend = set.afterSend || function(){}; }; var setting = new __setup(); var ajax = function(set){ var xhr = $G.getXhr(); if(typeof set !== "object"){return xhr;} }; ajax.setup = function(set){ setting = new __setup(set); }; ajax.getSetting = function(){return setting;}; return ajax; }()); /*** Other ***/ $G.scroll = function(){/*****/}; $G.serialize = function(){/*****/}; // и т.д. и т.п... return $G; }()); Только вот непонятно. Вот в примере есть внутренние переменные: __setup и setting. Если они используются в других функциях, то они получается остаются жить после завершения работы функции обертки? |
Ну да. В этом вся суть замыкания. Я думал раз уж вы его используете для своей библиотеки, то понимаете что это такое...
|
Если твоя библиотека делится на модули, и они зависимы друг от друга, то ты можешь использовать паттерн "иньекция зависимости", вот держи братишка, я тебе иньектор принес:
var module = new function () { var modules = {}; function inject(factory) { var require = factory.toString() .match(/\(([\s\S]*?)\)/)[1] .match(/[\$\w]+/img) || []; return factory.apply(null, require.map(module)); } function module(name, factory) { if (!factory) { var module = modules[name]; return module.instance || (module.instance = inject(module.factory)); } modules[name] = { factory : factory, instance: null }; } return module; }; работает функция module так // описываем модуль module('http', function () { return { ololo: function () { alert('ololo!') } } }); // обращаемся к модулю var http = module('http'); http.ololo() // ololo! вторым аргументом передается функция "фабрика", тот обьект который она вертет он и будет модулем, и он будет возвращаться при module('http'). Все модули создаются только один раз, так что module('http') === module('http'). Если какой-то модуль зависит от другого модуля то мы можем в коде одного модуля обратиться к другому: module('http', function () { return { } }); module('ajax', function () { // обратились из одного модуля к другому var http = module('http'); return { } }); но лучше просто написать ИМЯ необходимого модуля в параметрах к функции фабрике) тогда туда ПО ИМЕНИ необходимй модуль и передастся. module('http', function () { return { } }); module('ajax', function (http) { http //модуль автоматически подключился по имени аргумента return { } }); Ну или если тебе не нужны всякие модули, иньекции, то используй просто такой шаблон: var myLibrary = new function () { function trim() { } function find() { } // функция которая не будет доступна извне, она является внутренней для библиотеки function select() { } // функции которые хотим сделать доступными пользователю return { trim: trim, find: find } }; |
Aetae,
Читал я про замыкания... много раз читал. Ну вроде как начал понимать, как это работает. Maxmaxmaximus12, Спасибо :) Интересный подход. |
Hapson, или к примеру, одна функция использует несколько служебных, тогда описывай так
var myLibrary = new function () { // утилитарная функция, которая может быть доступна всем функциям фреймворка // тут вверху помещай более общие функции, выполняющие рутиную работу. // начинается с одного подчеркивания, как символ того что она вспомогательная. function _getElement() { } // публичная функция this.trim = new function () { // служебная функция которая видна только функции trim function find() { } return function () { // код функции trim } }; // публичная функция this.ajax = new function () { // служебная переменная, которая видна только функции ajax var ajaxPort = 80; // служебная функция которая видна только функции ajax function ajaxSettings() { } return function () { // код функции ajax } }; }; а вообще лучше разбивать код на модули и пихать их в разные файлы, а потом делать сборку проекта в один файл с помощью прогарммы gulp |
Судя по твоему коду и объяснениям, ты пишешь еще одну jquery. Не вижу смысла. Используй уже существующую и будет тебе счастье :)
Можешь к ней плагин дописать. Сразу почувствуешь себя Д'Артаньяном :D Кроме того, без опыта не напишешь. Даже если напишешь, то потом придется покрывать тестами. |
Цитата:
PS чтобы понимать как работает тот же jquery, нужно понимать как работает js. |
Цитата:
Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Каждый учит по-своему. Кто-то зубрит, а кто-то пишет велосипеды. Я так учил php. Два месяца чтения ни к чему не привели. Месяц писанины с попутным чтением мануала дал огромный результат. |
Hapson, нет, я считаю тебе надо писать свои велосипеды, только лучше оригиналов. Делай например какой нить jQuery подобный метод, только с лучшим апи. и.т.п. На велосипедах и надо учиться, а быдло когда говорит что это бесполезно имеет ввиду что это бесполезно делать на работе во время разработки сайта, лучше использовать готовое. Тут же быдло просто тупит и не понимает что ты пишешь эту либу ня ДЛЯ ТОГО ЧТОБЫ ВЫПОЛНИТЬ НА НЕЙ ЗАКАЗ КОТОРЙ ТЫ СЕЙЧААС ДЕЛАЕШЬ, а для того чтобы потренироваться. Мне знаешь как часто такие вот кукаретики говорили "не пиши это, это велосипед, используй готовое". И я выше обяьснил почему они так говорят. Потому что они тупят и путают писать либу для тренировки скилла, и писать либу для решения задачи. Ты пишешь для тренировки скилла. Если бы тебе понадобилось сделать за неделю сайт , то ты бы испоьзовал готовые либы.
Быдло просто путает все, потому что оно тупое) никогда их не слушай. |
Hapson, слушай Maxmaxmaximus - это признанный мастер написания велосипедов. Пятый год он их пишет один за другим и пока не дописал до логического конца ни одного. Это выдающийся показатель, можешь мне поверить. О "работе для быдла" и упоминать не стоит.)
|
Maxmaxmaximus12,
Спасибо, о том и речь. Aetae, :) Не, я вроде довожу до конца. Я начал с изучения php, и начал писать блог. Это было год назад. Теперь имею много самостоятельных кусочков на php и js из которых можно по-быстрому состряпать сайт. Но главное - опыт, который получаешь при написании очередного куска сайта. К примеру я две недели писал подсветку синтаксиса на js, хотя таких скриптов тьма - ну не понравился мне ни один из них. |
Цитата:
У меня есть цель - набить скилл - писание велосипедов реализует эту цель, использования готовых бил - НЕ реализует этуцель. Логично выбирать то, что реализует цель, нежели чем то что не реализует цель, иначе не реализуешь цель. Если цель - набить скилл, то надо писать велосипеды. Если цель сделать проект, то писание велосипедов не реализует эту цель, использование готового реализует эту цель, логично выбирать то что реализует цель, нежели чем то что не реализует цель. Если цель сделать проект, то логично использовать готовое. Разне цели, разные средства достижения цели.\ Быдло протсо думает, ПО КАКОЙ-ТО НЕВЕДОМОЙ ПРИЧИНЕ КСТАТИ, что когда люди пишут велосипеды, они пишут их ДЛЯ КАКОЙ-ТО ДРУГОЙ НЕВЕДОМОЙ ЦЕЛИ КРОМЕ КАК ПОТРЕННИРОВАТЬСЯ. Цитата:
Он пытался поймать тебя в логическую ловушку, ну или сам тупанул, он преподнес так как будто бы "ты не доводишь велосипеды, на которых тренеруешься, до конца" это что-то плохое. Но это НЕ что-то плохое. ВООБЩЕ В ЖИЗНИ что то недоводиить до конца это типа плохо, и он думал что мы начнем проэцировать это и написание велосипедов в целях треннировки)) Ты попался в логическую ловушку. )) НЕ ДОВОДИТЬ ДО КОЦА в данном случае тренировки на велосипедах было бы ПЕРЕСТАТЬ ТРЕНИРОВАТЬСЯ ДО ТОГО как поймешь КАК ПИСАТЬ ЭТОТ ВЕЛОСИПЕД. Вот тогда это было бы недоведением до конца, а качество велосипеда и его завершенность НУ СОВЕРШЕННО не связаны с процессом твоего обучения). Цель какая? Натреннировать скилл и понять как пишется этот велосипед. Цель = написать велосипед? - нет. А он думает что да). Почему? Потому что обычные люди не очень смышленые, и часто делают логические ошибки. Цитата:
|
Цитата:
1) ты можешь глядя на все это со стороны, придумать более крутой прием. 2) если не придумаешь, ты можешь использовать этот 3) например ты не знал что можно писать var qq = new function(){ }; и я когда-то не знал, просто подглядел где-то. Так и тут. Язык програмирования впрочем ты тоже подглядел где-то)) в этом ничего такого нет) все новые знания создаются на основе уже узнанных. |
Цитата:
К примеру реализацию того же ajax я увидел именно в доке jquery. Но я посмотрел только обертку, как оно внешне выглядит. Внешне красиво и удобно, а внутренности сам напишу, как оно мне нужно. |
А Я СКАЗАЛ что ты должен смотреть приемы которыми пишет JQUERY и АНАЛИЗИРОВАТЬ ИХ.
Паттерн коллекция знаешь? Вначале ты должен пытатсья повторить поведение фреймворка своими силами, потом смотреть как сделали они и сравнивать, потом на основе этого переделать свой метод чтобы он бул ЛУЧШЕ чем у них, если он еще не лучше чем у них. |
Скажу по большому секрету - я тоже пользователь такого метода обучения. И ничего хорошего по сравнению с классическим он мне не принёс. Не принёс и Максимусу, что очевидно. И тебе - тоже не принесёт. :) :(
|
Цитата:
|
Часовой пояс GMT +3, время: 02:55. |