×Закрыть

JS :: Namespaces

Всем привет.

Возможно изобрёл очередной велосипед, однако не нашёл нормальных легковесных решений Subj на JS.

Собственно вот мой пост: rostislav.nikitin.myblog.dp.ua/...016/05/26/srd-js-namepace
Читайте, пользуйтесь на здоровье.

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Кстати, раз уже зашёл разговор о транспайлерах. Подскажите, какие хорошие решения есть для поддержки html5 в старых браузаерх. Т.е. например у меня старый браузер, но я пишу код один раз на html5 + прикручиваю какой то набор скриптов там css и в любом браузере имею корректное отображение. Я понимаю, что это звучит как то очень фантастически, но мало ли, возможно есть какие то частичные решения.

Что имеется ввиду под хтмл5? Теги новые?

1.Новые тэги
2. Новые атрибуты
3. Behavior (Placeholer, ...)

Частично могут спасти полифилы, частично feature detection + graceful degradation, частично postcss. Вообще это проблема комплексная и решать ее кроме как комплексно не получится. Серебряной пули, увы, нет.

Понял... Вижу с 2001 ого мало что изменилось по сути )
Тут вылечить может только время, когда процент старых браузеров приблизится к 0 c точностью 0.001 :) И останутся только HTML5 Ready...
Кстати, а как в новых IE с боксинг моделью ? Хоть это вылечили ?

Ну как бы уже редкость поддержка ИЕ8-9

А классику в виде книги Стефанова отменили?

Да нет, никто не отменял. Я сделал что-то похожее. Вот как в книге:

MYAPP.namespace = function (ns_string) {
  var parts = ns_string.split(‘.’),  parent = MYAPP,  i;
 // отбросить начальный префикс – имя глобального объекта
 if (parts[0] === “MYAPP”) {
   parts = parts.slice(1);
 }
 for (i = 0; i < parts.length; i += 1) {
   // создать свойство, если оно отсутствует
   if (typeof parent[parts[i]] === “undefined”) {
     parent[parts[i]] = {};
   }
   parent = parent[parts[i]];
 }
 return parent;
}

У меня тоже самое почти. Другое дело, что я просто это вынес в отдельный модуль с сделал доступным для скачивания, что бы девелопер нажал пару кнопок (скачал из GitHub модуль) и у него есть ns(...)...

Просто я сейчас в шаблонах копаюсь. Учу не спеша. И буквально недавно наткнулся.

а на крайняк юзали следующий паттерн

var moduleA = global.moduleA || {};
var moduleB = moduleA.moduleB || {}
для больших проектов не подходит (там можно другие решение использовать), но для очень маленких более чем работает

Да, именно для маленьких.
Прошлый проект, на котом мне довелось работать, скажем так, не очень маленький. Это была CRM система и команда из нескольких разработчиков.
Был принят подход: один файл — один модуль.
Если длинна неймспейса более чем 2-3 — начинает напрягать в каждом файле проверять: а есть ли такой неймспейс, а есть ли неймспейс второго уровня и т.д. Лишняя работа и выглядет не наглядно.
Я же предлагаю очень простой и лаконичный подход:
ns("Namespace1.Namespace2...NamespaceN"); // This is a clear compact code

если проект большой, смотри мой комент ниже

Подскажите, а как при помощи этих фреймворков выглядит создание неймспейса ?

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

и там вы namespace создадите когда положите файл в папочку, имя этой папочки и будет выступать неймспейсом

А, всё, вспомнил — да, есть такое дело.
А если например я некой тулью заждоиню все JS файлы в один, потом обожму каким-то минимайзером всё это добро.
Оно будет работать ?
Просто это реальный кейс. У нас на бэк энде в каком то из проектов, всё добро собиралось в один большой JS файл, там же обжималось и кешировалось...

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

Очень интересно. Спасибо за инфо.

AMD и CommonJS лучше пропустить и сразу переходить к ES6 modules

AMD и CommonJS лучше пропустить и сразу переходить к ES6 modules
Так а что уже все на ES6 перешли ? Я понимаю корпоративный софт можно переводить на новые рельсы — сказал всем проапдейтить браузер и все проапдейтили. А как быть с internet ?

И ещё...
Я как то был на MS Swit и человек из Google вообще говорил, что теперь можно будет писать на плюсах свои extensions под браузеры. Это так ? Или это в долгой перспективе и с кучей ограничений и т.д. ?
И как обстоят дела (если кто в курсе) с HTTP2 который всё грозятся внедрить ?

Так а что уже все на ES6 перешли?
Этот вопрос перешел в разряд риторических после появляние production-ready версии бабеля.

Да и вообще ES6 modules — это де-факто такая же спека как и AMD и CommonJS, только нативная, скажем так, которую рано или поздно нативно реализуют все браузеры.

А пока дело до повсеместного внедрения HTTP/2 не дошло можно ES6 модули собирать каким-нибудь продвинутым бандлером с tree-shaking (ну например rollup или будущим webpack2).

Этот вопрос перешел в разряд риторических после появляние production-ready версии бабеля.
Т.е. грамотные ребята сделали эмулятор. Радует.
А пока дело до повсеместного внедрения HTTP/2 не дошло можно ES6 модули собирать каким-нибудь продвинутым бандлером с tree-shaking (ну например rollup или будущим webpack2).
Понято. Спасибо за разъяснения !

Так а как насчёт писать externsions на плюсах, никто особо не заморачивался этой темой ? А то это вообще рывок для корпортивного software и не только для корпоративного. Там всякие аппаратные DirectXы и прочие думаю тогда можно будет юзать и вообще аппилкухи будет проще писать с Rich UI и которые железо юзают по полной...

Т.е. грамотные ребята сделали эмулятор. Радует.
Только не эмулятор, а транспайлер. В принципе, щас в ES3/5 можно оттранспайлить что угодно, хоть эту вашу джаву, хоть хаскель, хоть брейнфак(наверное). Всё будет зависеть от необхоимости поддерживать древние стандарты для совместимости с древними ИЕ. По своему опыту скажу, что ES6/ESNext код с эпизодическими вкраплениями совсем экзотических вещей из stage1/stage2 вполне себе нормально доводится бабелем до состояния поддержки ИЕ8 и вполне себе бодренько крутится в продакшне.
Так а как насчёт писать externsions на плюсах, никто особо не заморачивался этой темой
Судя по всему речь о webassembly
medium.com/...a-61256ec5a8f6#.mowm60s0u
Только не эмулятор, а транспайлер.
Да, точно
По своему опыту скажу, что ES6/ESNext код с эпизодическими вкраплениями совсем экзотических вещей из stage1/stage2 вполне себе нормально доводится бабелем до состояния поддержки ИЕ8 и вполне себе бодренько крутится в продакшне.
(y)
Судя по всему речь о webassemblymedium.com/...a-61256ec5a8f6#.mowm60s0u
Да ! Именно. Спасибо за ссылку ! Будет что почитать )

Пока эта тема в разработке, но скоро должна быть, вроде будут все браузеры поддерживать.

Ой сколько мы это уже слышали о том что все браузеры будут поддерживать ))) Но посмотрим, мало ли. Интересно, какие там ограничения. По моим личным ощущениям — это потенциальная дыра. Находка для крякеров. Я правда мало что знаю об этой технологии, но когда речь идёт о загрузке выполнении бинарного кода, то почему то у меня сразу в воображении картина как кто-то себе ставит плагин с трояном и т.д. )

лично я сейчас использую es6 modules и для сборки использую babel (и не только для сборки), это тот о котором писали ниже

Да, интересная вещица. Особое внимание уделил: React preset. Вижу тут уже реализована идея создания классов: React.createClass...

это опционально, но многие вместе с реактом его используют

Помница в Mootools только была раньше поддержка ООП... Подскажите, а вообще как сейчас в JS с ООП (только в ES5) ? Куда бы Вы рекомендовали посмотреть в этом направлении ?

ну если речь идет об ES5, то я бы просто реализовывал ООП, так сказать естественным способом:

function Parent () {
}

Parent.prototype = Object.create(null);

Parent.prototype.parentMethod = function () {};

.....

function Child () {
}

Child.prototype = Object.create(Parent.prototype);

некоторые либы имеют «сахар» для классов, к примеру ExtJS
вообще все зависит от ваших задач, и условий

ну если речь идет об ES5, то я бы просто реализовывал ООП, так сказать естественным способом:
Ну я бы не сказал что это ООП :) А где же области видимости, настоящее наследование и т.д. В общем как бы такое... На самом деле возможно и не надо в JS вообще лезть со своим ООП.... Язык на это не рассчитан. Но просто бывает очень хочется )))

По поводу задач. Есть ли что-то лагковесное которое может:

var myNewType = createType(
// Members
{
  constructor: function(param1, ..., paramN) { ... },
  static:
  {
    private: 
    {
      myPriateStaticMethod: function(...) {}, ...
    }
    public:
    {
     ...
    }
  }
 private:
 {
    myNonStaticPriateMethod: function(param1, ..., paramN)
    {
      _base.inheritedInstanceLevelMethod(param1);
       // Some my code
    }
 },
 public:
 {
    ..
 }
}, 
// Options
{
  baseClass: Namepsace1.Namespace11.SomeClass, ...
});

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

но в js не класс-ориентированное ООП, даже то что в ES6, это просто сахар над тем что я написал.

вообще, если вам классического ООП хочется то смотрите в сторону TypeScript

Не, как бы нам никто не мешает делать такое:

var myNewType = (function()
{
  // Private statics
  function PrivateStatic() {};
  // Constructor
  function constructor()
  {
    // Private instance
    var filed1 = ..., fieldN = ...;
    function PrivateInstance() {};

    // Public instance
    this.PublicInstance = function()
    {
    ...
    }
  }
  
 // Public static

  constuctor.PublicStatic = function() {};
  
  return constructor;
   
})();

Но думалось, может есть кто-то кто сделал createType — в котором явно есть хэши с именами static, private, public и т.д. Котоорая потом собирает из этого добра класс.... Ну и например в конструктор допишет

var _base = new options.baseClass(...);
Типа:
constuctor = new Function('var _base = new options.baseClass(...);' + constuctor.toString());

выглядить не очень, и нарушается следующие условие:

function Test() {this.test = function () {}}
new Test().test === new Test().test // false :(
а так есть полно либ в интернете которые делают примерно что вы хотите, просто их в большинстве случаев их никто не хочет использовать, да и не нужно оно. вопрос привычки не более
function Test() {this.test = function () {}}
new Test().test === new Test().test // false :(
Так а как может быть по другому ?
Два разных инстанса, и в каждом из них два разных объекта типа Function. Естественно будет false... Или я чё то не понимают ? Если бы было что-то типа:
function Test() { this.test = 10; }
new Test().test === new Test().test // true. 

Т.к. тут не объектный тип. Т.е. в JS как и во многих языках, объект — это по факту ссылка не область в памяти и сравниваются именно адреса, а не сожержание... В то время как простые типы: Number, Boolean, .. сравниваются по значению. Я уже сейчас не помню где их хранит JS, но если не ошибаюсь в function sope стеке...

все правильно, просто если использовать прототипы (как в моем примере выше), то это условие будет удовлетворятся

Получается по факту в созданном классе будут не те функции, которые передали для его создания, а точно такие же (по содержанию), но с разным адресом... Но на самом деле, это и не страшно. Просто надо это осознавать, что когда мы делаем creteType({... тут мы передём описание memberов, т.е. фактически их текст. И завязываться на ссылки не стоит }). Опят же если сдеолать createType({}, someInitialStaticObject) — ссылку на этот объект без проблем можно передать в билдер типа и он передаст её в функцию создания типа и она будет видна в самом типе... Как бы решаемо...

ну как сказать не важно, зависит от того что девелоперы наваяют (а в джс много чего можно написать, чего не стоило бы).

видел не однократно в проектах следующие вещи:
ктото переопределяет в рантайме метод, к примеру хотим врапнуть какойто вызов, и добавить хук на другой вызов, часто такое делается с какимито библиотекамим, которые не особо расширяются, а потом мы в какомто месте человек хочет проверить, оригинальный ли это метод, или нет, и в зависимости от этого разная логика. а потом баги сыпятся... :(

поверьте, это реальные проблемы

Да, не спорю. Проблем в JS всегда хватало. Свобода в JS является обратной стороной высоких требований предъявляемых к JS девелоперам. Так как всё таки не strict type язык и из-за историй типа «забыл», «ой, а я думал...» и т.д. потом вылазят грабли... :) Тут тебе компилятор не скажет — Дружище, у тебя тут тип тришечки не тот и т.д... :) Я на скрипте писал где-то в 2001 — 2005 серьёзно и на системе, был фулл стек девом. И на то время JS девы вообще получали гроши. Я не мог понять почему ? Ведь гемора на порядок больше... Ну потом понял, что просто это мы там писали на тот момент высокотехнологичное AJAX приложение. А в большинство контор нужны были верстальщики с умением сделать что бы кнопочка там блымала и т.д. :) Но сейчас вижу ситуация кординально поменялась. Выросла сложность клиентских приложений со всеми вытекающими...

как по мне самая большая проблема фронтенд это браузеры, и не один фреймворк этого не пофиксит =(

в целом сейчас тоже ничего сложного, надо в большинстве случаев накидать формочек на ангуляре, но стало больше сложных приложений с кучей логики, и не самым простым в имплементации UX

Даааа, браузеры это отдельная тема ))) И с каждым годом их становится всё больше и больше )

Кстати, по поводу прокси и функций.
Если делать:

ns("MyNamespace.Proxies").createType("MyProxy" ,
{
  constuctor: function(methodToWrapName, methodToWrapRef)
  {
    this[methodToWrapName] = function()
    {
      methodToWrapRef.apply(this, arguments);
      // Some other logic
    }
  }
});
А потом:
targetObject.methodToWrap = new MyNamespace.Proxies.MyProxy("methodToWrap", targetObject.methodToWrap);
то с предложенным вариантом реализации createType не должно быть проблем. Опять же, зависит от конкретной ситуации.
выглядить не очень
Вооот :) По этому и хочется что то типа createType(...) :)

Бррр... А defineproperty уже отменили, или речь идет о других стутиках, привитах публиках ритаблях. ??

Та нет, не отменял никто, просто саппортится не всеми браузерами. На сколько я заню — это в ES5 появилось.

Ну и да, как бы хотелось бы раз уже зашла речь об ООП: показывать наружу только то что можно... типа инкапсуляция и всё такое.

Ростислав, поясните в чем соль плиз для тех кто сидит на бабеле.

Соль в том, что это не для нас :)

Светлана, я уже давно сижу на «Backend» девелопменте, поэтому не сильно сейчас слежу за новыми течениями в FrontEnd разработке. Подскажите что такое бабель ? И как в нём реализована идея создания неймспейсов ?

Подписаться на комментарии