Как стать автором
Обновить

Namespaces в JavaScript. Ставим точку в вопросе

Время на прочтение3 мин
Количество просмотров7.3K

Развитие языка javascript переносит выполнение кодов на распределенную сеть пользователей и снимает нагрузку с сервера. Это разумный подход. Введение в js ключевых слов class, extends и static дало возможность легко моделировать классами и объектами предметную область проекта. Это замечательно. Следующий вопрос, который необходимо рассмотреть при возрастании сложности js-проекта - это пространство имен. Именно оно позволяет избежать конфликтов с ворохом разнородных js-скриптов. Как показывает практика с этим вопросом почему-то возникли большие сложности. Смотрим ссылки ниже:

https://support.qbpro.ru/index.php?title=Базовые_Namespace_паттерны_JavaScript

https://habr.com/ru/post/527610/

https://drbrain.ru/articles/js-namespaces/

https://stackoverflow.com/questions/881515/how-do-i-declare-a-namespace-in-javascript

Плохо, только запутали все и многие решения сложны.

Есть еще и стандартная схема с использованием import, export модулей:

https://learn.javascript.ru/modules-intro

https://habr.com/ru/company/domclick/blog/532084/

За модулями конечно будущее, но с ними возникает пара вопросов - это локальное их использование без сервера (CORS policy), а главное поддержка их браузерами все еще не завершена (многопоточно web-workers не обработают модули, старые браузеры тоже не понимают):

https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Modules

Многопоточный веб-worker по-своему захватывает скрипты:

https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts

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

/** 
 * @namespace namespaceOne
 */
const namespaceOne = new function(){    
    class First {
        //статическое свойство
        static className = "First";
        constructor() {
            console.log("class First consructed");
        }

        print() {
            console.log("First print");
        }

        //статическая функция
        static printStatic() {
            console.log(First.className + " static print ");
        }
    }

    //наследование
    class Second extends First {
        constructor() {
            super();
            Second.className = "Second";
            console.log("class Second consructed");
        }
        //полиморфизм
        print() {
            console.log(Second.className + " print");
        }
    }

    class Third {
        className;
        encapsulation;
        constructor() {
            this.className = "Third";
            this.encapsulation = new Second(); //инкапсуляция
            console.log("class Third consructed");
        }
        print() {
            console.log("Third print");
        }
    }
    console.log("namespaceOne code done");
    //экспорт пространства имен
    return {First: First, Second: Second, Third: Third};
};

/** 
 * @namespace namespaceTwo
 */
const namespaceTwo = new function(){    
    class First {        
        constructor() {
            console.log("other class First consructed");
        }

        print() {
            console.log("other First print");
        }       
    }
    //экспорт пространства имен
    return {First: First};
};

/** 
 * @namespace namespaceThree
 */
const namespaceThree = new function(){
    //импорт пространства имен
    namespaceOne.First.printStatic();
    let second = new namespaceOne.Second();
    second.print();

    let ThirdClass = namespaceOne.Third;
    let third = new ThirdClass();
    third.print();
    
    let first1 = new namespaceOne.First();
    let first2 = new namespaceTwo.First();
    first1.print();
    first2.print();
};

Теперь можно смело добавлять ваш код в любой проект. С большой вероятностью конфликтов не возникнет. Минус такого решения: надо добавлять комментарии, что вот такие конструкции: const namespaceYou = new function(){...} - являются namespace, а не чудной функцией.

Есть и более простой вариант не засорять общее пространство кодом (некоторая экологичность так сказать) - это просто взять ваш код в фигурные скобки { } и не злоупотреблять модификаторами var и function:

{ //namespace1
    class Simple {
        constructor() {
            console.log("Simple created");
        }
        print() {
            console.log("Simple called");
        }
    }

    let simple = new Simple();

    //экспорт 
    var namespace1 = {simpleObject: simple, SimpleClass: Simple};
}

{//namespace2
    namespace1.simpleObject.print();
    let simple = new namespace1.SimpleClass();
}

Красота.

Когда нибудь веб-workers начнут работать с модулями, а CORS policy разрешит писать вам локальные модульные js-приложения и все это уйдёт в историю. Когда-нибудь ...

Теги:
Хабы:
Всего голосов 20: ↑0 и ↓20-20
Комментарии9

Публикации

Истории

Работа

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн