Vitamin – сервис для выгодного управления вашей рекламой
  • Все популярные рекламные сети в одном окне
  • Агентское вознаграждение до 16% на личный счет или рекламу
  • Любые дополнительные услуги под ваши потребности
  • Бесплатное обучение маркетингу
  1. Главная >
  2. Блог >
  3. Основные принципы формирования и структуризации JavaScript

Основные принципы формирования и структуризации JavaScript

js script

JavaScript – это очень любопытный язык. На нем очень легко писать код, но достаточно сложно его изучить.

Почему JavaScript`ом трудно овладеть?

При написании JS кода важно помнить что, прежде всего, это динамический язык. Это означает, что существует много способов сделать разные вещи. Вам не придется иметь дело с сильно типизированными классами, или с более сложными функциями языков, таких как C # и Java. Это как благословение и проклятие одновременно.

Усовершенствование JS

Namespaces

Один из недостатков того, как JavaScript реализуется, это то, что он работает на вершине глобального объекта. В случае браузера, это означает window объект. Поэтому, в любое время, когда присутствует такой код на странице…

function doStuff(){
    alert('Привет! Я работаю!');
}

function doMoreStuff(){
   var images = document.images.length;
   console.log("Имееется " + images + "на этой странице");
}
doStuff();
doMoreStuff();

Функции doStuff и doMoreStuff сразу доступны глобальному window объекту.

windowmo

Это означает, что если кто-то прийдет и попытается написать функцию, которая также называется doStuff, то тогда произойдет конфликт! Все script теги, в основном берут код внутри себя, и работают против window, в том порядке, в котором на них ссылаются в HTML. В результате, второй человек при реализации doStuff, перепишет первый doStuff.

Распространенный метод устранения этой проблемы, это использование либо самоисполнительной анонимной функции или namespace. Объектно-ориентированные люди, читающие это, вероятно, уже знакомы с концепцией namespace, но основная идея состоит в том, чтобы сгруппировать функции в различных областях для повторного использования.

var NS = NS || {}; // "Если NS не определен, тогда сделайте его равным пустому
объекту"
NS.Utils = NS.Utils || {};
NS.Models = NS.Models || {};
NS.Views = NS.Views || {};

Это позволит предотвратить загрязнение глобального namespace, и будет способствовать читаемости вашего приложения. Теперь, вы можете просто определить функции в своих namespace. Общепринятым namespace, является app, которое управляет остальными частями приложения.

Шаблоны проектирования и практика

В каждом из языков, существует множество шаблонов проектирования. Часто используемым паттерном является Revealing Module.

NS.App = (function () {
    // Инициализация приложения
    var init = function () {
        NS.Utils.log('Application initialized...');
    };

    // Верните общедоступный метод для App
    return {
        init: init
    };
}());

NS.App.init();

Выше, функция App определяется в NS объекте. Внутри, определяется функциональная переменная для init, и возвращена как anonymous object literal. Обратите внимание, что в конце, есть дополнительный набор скобок: }());. Это вынуждает NS.App функцию автоматически выполняться и возвращаться. Теперь, вы можете вызвать NS.App.init () для инициализации вашего приложения.

Анонимная функция выше, является наилучшей практикой в JavaScript, и еще её называют Self-Executing Anonymous Function (само-исполнительная анонимная функция). Поскольку у каждой функци в JavaScript есть своя собственная сфера – то есть переменные, определенные внутри функции не будут доступны вне их, это делает анонимные функции, полезными во многих вещах.

// Оберните код в SEAF
(function (global) {

    // Теперь любые переменные, которые вы объявить здесь,не будут доступны снаружи.
    var somethingPrivate = 'you cant get to me!';

    global.somethingPublic = 'but you can however get to me!';

}(window));

console.log(window.somethingPublic); // This works...
console.log(somethingPrivate); // Error

В этом примере, так как функция автоматически выполняется, вы можете передать window на выполнение }(window));, и он будет представлен в качестве global внутри анонимной функции. Эта практика ограничивает глобальные переменные в window объекте, и оказывать помощь в предотвращении конфликтов имен.

Теперь вы можете начать использовать SEAF в других областях вашего приложения, чтобы сделать код более модульным. Это позволит избежать повторного использования вашего кода, а также поспособствует хорошему разделению интересов.
Вот пример потенциального использования этих идей:

(function ($) {
    var welcomeMessage = 'Welcome to this application!'

    NS.Views.WelcomeScreen = function () {
        this.welcome = $('#welcome');
    };

    NS.Views.WelcomeScreen.prototype = {
        showWelcome: function () {
            this.welcome.html(welcomeMessage)
                .show();
        }
    };
}(jQuery));

$(function () {
    NS.App.init();
});

// Измените App.init выше
var init = function () {
    NS.Utils.log('Application initialized...');
    this.welcome = new NS.Views.WelcomeScreen();
    this.welcome.showWelcome();
};

Итак, здесь происходит несколько разных вещей. Во-первых, jQuery передается в качестве аргумента в анонимную функцию. Это гарантирует, что $ на самом деле является jQuery внутри анонимной функции.

DOM запросы, могут занимать большой объем памяти, поэтому, пожалуйста, кэшируйте их как можно больше.

Затем, мы обворачиваем (wrap) App init внутри $(function(){});, что было бы эквивалентно $(document).ready().

Шаблон Наблюдатель (Observer Pattern)

Еще один отличный шаблон – Наблюдатель. Этот паттерн позволяет нам подписаться на DOM события, такие как click и mouseover. С одной стороны, мы слушаем эти события, и с другой стороны, публикуем эти события, например, когда браузер публикует (или объявляет), что кто-то нажал на конкретный элемент. Существует большое количество библиотек для шаблона наблюдателя, так как это достаточно короткий фрагмент кода.

// Модель данных для получения новостей.
NS.Models.News = (function () {
    var newsUrl = '/news/'

    // Получить новости
    var getNews = function () {
        $.ajax({
            url: newsUrl
            type: 'get',
            success: newsRetrieved
        });
    };

    var newsRetrieved = function (news) {
        // Публикация поиска новостей
        amplify.publish('news-retrieved', news);
    };

    return {
        getNews: getNews
    };
}());

Этот код определяет модель для извлечения новостей из какого-то сервиса. Как только новость была получена с помощью AJAX, срабатывает newsRetrieved метод, проходя через извлеченные новости для Amplify, и публикуется на news-retrieved тему.

(function () {
    // Создайте просмотры новостей.
    NS.Views.News = function () {
        this.news = $('#news');

        // Подпишитесь на событие поиска новостей.
        amplify.subscribe('news-retrieved', $.proxy(this.showNews));
    };

    // Показать новости, когда они прибыли
    NS.Views.News.prototype.showNews = function (news) {
        var self = this;
        $.each(news, function (article) {
            self.append(article);
        });
    };
}());

Этот код является способом для отображения полученых новостей. В конструкторе News, Amplify подписывается на news-retrieved тему. Когда эта тема будет опубликована, сработает showNews функция. Затем новость добавляется в DOM.

// Модификация App.init выше
var init = function () {
    NS.Utils.log('Application initialized...');
    this.welcome = new NS.Views.WelcomeScreen();
    this.welcome.showWelcome();

    this.news = new NS.Views.News();

    // Получи новости!
    NS.Models.News.getNews();
};

Изменените init функцию из приложения, чтобы добавить поиск новостей … и все готово! Теперь, у вас есть отдельные части приложения, каждый из которых отвечает за одну операцию. Это также известно, как Принцип Единой Ответственности (Single Responsibility Principle).

Документация и Файлы + Минификация

Один из ключей к поддерживаемому коду любого рода – не только JS – это документация и комментарии. Комментарии могут стать драгоценными для новых разработчиков приступающих к проекту, с необходимостью понять, что происходит в коде. Отличный инструмент для создания документации называется, Docco. Это тот же самый инструмент, который генерирует документацию для веб-сайта Backbone.js. В основном, он берет ваши комментарии, и помещает их рядом с вашим кодом.
Есть также инструменты, такие как JSDoc, которые генерируют документацию API стилей, описывая каждый класс в коде.
Другое дело, которое может оказаться трудным, при запуске нового проекта, это попытки определить, как лучше организовать код. Один из способов заключается в разделении функциональных элементов в отдельные папки. Например:

  • /app.js
  • /libs/jquery.js
  • /libs/jquery-ui.js
  • /users/user.js
  • /views/home.js

Эта структура помогает сохранить части функциональности, отдельно друг от друга. Есть, конечно, несколько способов организации кода, но все, что действительно имеет значение, это принятие решения о структуре. Далее, вы можете использовать инструменты сборки и минимизации. Есть много вариантов:

  • Grunt
  • Google Closure
  • JSMin
  • YUI Compressor

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

AMD

Асинхронный Определение Модуля (Asynchronous Module Definition) является иннымспособ написания JavaScript кода, он делит весь код в отдельные модули. AMD создает стандартный шаблон для написания этих модулей, чтобы загрузить их в код асинхронно.

Использование script тегов блокирует страницы, так как они загружается до тех пор пока DOM не будет готов. Поэтому, используя что-то вроде AMD, позволит DOM продолжать загрузку, в то время как скрипты также еще грузятся. По существу, каждый модуль делится на свой собственный файл, и также есть один файл, который стартует процесс. Самая популярная реализация AMD является RequireJS.

// main.js
require(['libs/jquery','app.js'], function ($, app) {
    $(function () {
        app.init();
    });
});

// app.js
define(['libs/jquery', 'views/home'], function ($, home) {
    home.showWelcome();
});

// home.js
define(['libs/jquery'], function ($) {
    var home = function () {
        this.home = $('#home');
    };

    home.prototype.showWelcome = function () {
        this.home.html('Welcome!');
    };

    return new home();
});

В сниппете выше, есть main.js файл, в котором начинается весь процесс . Первый аргумент к требованию функции представляет собой массив из зависимостей. Эти зависимости являются списком файлов, которые необходимы для app.js. По окончанию загрузки, вернувшийся модуль передается в качестве аргумента функции обратного вызова справа.
Кроме того, есть app.js, который требует jQuery, а также view. Следующее, view home.js требует только jQuery. У него есть home функция внутри, и он возвращает экземпляры самого себя. В приложении эти все модули хранятся в отдельных файлах, что делает приложение очень легким в управлении.

Высоких конверсий!

blog comments powered by Disqus
Vitamin – сервис для выгодного управления вашей рекламой
  • Все популярные рекламные сети в одном окне
  • Агентское вознаграждение до 16% на личный счет или рекламу
  • Любые дополнительные услуги под ваши потребности
  • Бесплатное обучение маркетингу
copyright © 2011–2024 Все права защищены
Запрещено любое копирование материалов ресурса без письменного согласия владельца — ООО "Феникс-Маркетинг". ИНН:7725812838, КПП:772501001, ОГРН: 513774619323915280, Москва, ул. Ленинская слобода, д. 19, стр. 1, этаж/пом 3/25

Генеральный партнёр: STRATE FZ-LLC License number 47005249 Address: B03-227 Business Center 02 RAKEZ Business Zone-FZ RAK (Ras Al Khaimah), United Arab Emirates Email: corporate@strate.ae