Написав 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 генерирует карту, основанную на "источнике", который вы ему даете.
Спасибо! это моя первая настоящая библиотека для клиента, поэтому я хочу убедиться, что она создана для текущих стандартов:)
Ответы
Ответ 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));