Подтвердить что ты не робот

Написав JS-библиотеку, я на правильном пути?

Я пишу JS API для веб-сайта, и я думаю, что я на правильном пути, но я хочу убедиться. Вот синтаксис и как я начал его писать:

(function( window, undefined ) {
  var bg = function(sel){
    var _api = {
      source: function(src){
        this.src = src;
        return this;
      },
      map: function(action){
        if(action == 'create'){
          document.write(this.src)
        }
        return this;
      }
    }
    return _api
  }
  window.bg = bg;
})(window);

Кажется, работает нормально, но правильно ли я правильно/правильно привязываюсь к this и вы видите потенциальные проблемы с этим методом? JS API/Lib генерирует карту, основанную на "источнике", который вы ему даете.

Спасибо! это моя первая настоящая библиотека для клиента, поэтому я хочу убедиться, что она создана для текущих стандартов:)

4b9b3361

Ответ 1

Вы, безусловно, на правильном пути! Использование немедленной функции дает вам хорошее закрытие, чтобы держать контроль над тем, что личное и общедоступное, а использование локальных запросов выполняется быстрее и обеспечить, чтобы глобальные переменные были такими, какими вы думаете, что они должны быть, я часто использую этот шаблон проектирования. Если вы хотите сравнить и сопоставить другие подходы, я бы посмотрел на Шаблоны JavaScript от Stoyan Stefanov, это быстрый просмотр всего за 200 страниц и полную практическую информацию.

this немного безопаснее, чем window, и вы, вероятно, захотите включить любые глобальные переменные третьей стороны, которые вы хотите использовать, например jQuery.

(function (window, $, undefined) {
// This pattern gives you the following benefits:
//   * all variables defined in here are private
//   * can safely minify global variables: window, jQuery & undefined
//   * ensures that window, $, undefined mean what you expect
//   * free bonus! global variables are localized so lookups are slightly faster
}(this, jQuery));

Ответ 2

Выглядит хорошо.:) Несколько рекомендаций, хотя:

Включить точку с запятой перед блоком следующим образом: ;(function () {

Если что-то включено до (function () {, оно попытается запустить его как функцию, с вашим определением в качестве первых аргументов. Поэтому, если вы хотели его в строгом режиме и имели:

"use strict"

(function () {

Он попытается запустить "use strict" как функцию, которая возникла бы с ошибкой, например Uncaught TypeError: [object String] is not a function.

Во-вторых, я предпочитаю делать это с помощью моего кода:

;(function () {
    var global = this;
    // Your stuff.
}).apply(this);

Похоже, это хороший старт.

Если вам нужны хорошие рекомендации, я бы предложил просмотреть файлы JavaScript, такие как jQuery и MooTools.

Избегайте писать код, например Dojo. Их код ужасен.

Ответ 3

Моя единственная "проблема" возвращает объект (_api) из конструктора и использует объект (this) в только что созданном конструкторе - значение возвращаемого конструктора. Я лично не вижу никакой дополнительной выгоды для этой суб-упаковки. Внешняя упаковка сама по себе является хорошей идеей (см. Ответы daniellmb).

Кроме того, я предпочитаю prototype -ориентированный подход к "OO" в JavaScript и только отклоняюсь от него в особых случаях. (Я не возражаю, если другие "воюют" с внутренними методами, если кто-то это делает, и они нарушают код, это не моя проблема;-) Это во многом вопрос вкуса, но для экземпляров многих многих объектов это может также работать лучше - в коде, размещенном выше каждого нового объекта, фактически является "singleton" с дублирующими функциями и связанными [[целями]].

Счастливое кодирование.

Ответ 4

(function(window, undefined) {
    // use a usefulname.
    function UsefulName(selector) {

    }

    function usefulName(selector) {
         return new UsefulName(selector);
    }

    UsefulName.prototype.source = function(src) {
        // private objects should start with "_"
        // this indicating the variable is internal by convention.
        this._src = src;
        return this;
    };

    function create() {
        //document.write(this.src);
    }

    UsefulName.prototype.map = function(action) {
        if (action === "create") {
             create.call(this);
        }
        return this;
    };

    window.usefulName = usefulName;
}(window));

Я бы рекомендовал использовать prototype для любых фреймворков/библиотек, поскольку он просто более эффективен.

Также используйте Полезное имя для вашей библиотеки. Вы можете использовать ._name как приватную переменную по соглашению. Ваши разработчики знают, что если они возится с любыми переменными/функциями "private", код будет ломаться, если они не знают, что там делают.

Я согласен с window.foo = foo; для переноса переменных в глобальную область.

Пример использования закрытий.

(function(window, undefined) {
    function UsefulName(selector) {
        var src;
        this.source = function(_src) {
            src = _src;
            return this;
        };

        var redirect = {
            "action": function() {
                 //document.write();
            }
        };
        this.map = function(action) {
            redirect[action].apply(this, arguments);
            return this;
        };
    }

    window.usefulName = function(selector) {
         return new UsefulName(selector);
    };
}(window));