Советы для среднего программиста javascript, чтобы написать лучший код


Итак, я довольно приличный программист javascript, и я только недавно закончил работу над довольно большим веб-приложением, которое включало написание довольно большого количества javascript. Одна из вещей, с которой я столкнулся, когда отлаживал свой сценарий, заключалась в том, что были некоторые конфликты пространства имен с моими различными глобальными переменными, которые я использовал в своем сценарии. По сути, мой javascript-файл был структурирован следующим образом:

global var a
global var b
global var c
function1(){}
function2(){}
function3(){}

С помощью функции jQuery document on-ready для привязки различных событий к кнопкам в моем html и вызов моих функций в качестве обратных вызовов обработчика событий.

Некоторые люди рекомендовали инкапсулировать весь мой сценарий в одну гигантскую функцию, чтобы предотвратить любые ошибки, связанные с областью действия. Я не мог точно понять, что это повлечет за собой. Любые советы приветствуются, поскольку я собираюсь создать еще одно веб-приложение, которое будет включать довольно много загрузок страниц AJAX, чтобы избежать обновления браузера и манипуляций DOM, связанных с различными событиями. Спасибо!

5 5

5 ответов:

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

Http://docs.jquery.com/Plugins/Authoring

Кстати, об этом спрашивали много раз (не критика за повторный вопрос)

I также очень рекомендую вам прочитать о плагине jQuery live для регистрации событий DOM (я думаю, что теперь он встроен): http://api.jquery.com/live/ (это сведет к минимуму неприятную необходимость в управлении состоянием развязки и повторной привязки узлов DOM).

Аналогичная альтернатива версии Майкла и ннннн-это сделать

var YourApp = {
    a: 1234,
    b: 5678,
    function1: function () {

    },
    etc
};

YourApp является единственным глобальным var, и его свойства могут быть доступны как

YourApp.function1();

Или

YourApp.a;

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

(function(exports) {

var MyClass = function() {

};

MyClass.prototype.method = function() {

};

// this won't be visible outside this file
var helperFunction = function() {

};

exports.module = exports.module || {};
exports.module.MyClass = MyClass;

})(window);

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

(function() {

this.Thing = function() { };

}).call(window);

я ожидаю получить понижение от ОО пуристов, но...

Очень простое решение конфликтов пространств имен-поместить переменные и функции в класс, даже если он не имеет работающего конструктора или выполняет какую-либо внутреннюю обработку самостоятельно.

function YourApp() {} // empty constructor...
YourApp.a = 1234;
YourApp.b = 5678;
YourApp.function1 = function() {};
YourApp.function2 = function() {};

function YourOtherApp() {} // empty constructor...
YourOtherApp.a = 1234;
YourOtherApp.b = 5678;
YourOtherApp.function1 = function() {};
YourOtherApp.function2 = function() {};

// Then you call it like:
YourApp.function1();

// And you have no more namespace collisions with other globals

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

Так соотносится, что непосредственно к примеру, который вы привели с a, b, etc:

var SNS = {}; // create some namespace object

SNS.a = "something";
SNS.b = "something else";
SNS.c = 17;
SNS.method1 = function(x) {
   alert(SNS.a + x);
};
SNS.method2 = function() {
   SSN.method1(12); // call another function
};

SNS.SUB = {};
SNS.SUB.property1 = "sub namespace prop 1";
SNS.SUB.method1 = function() {};
// etc.

В моем примере используется " SNS " для "некоторого пространства имен"; я уверен, что вы сразу увидите, как это было бы довольно легко применить к проекту, который вы только что закончили. Вы, вероятно, также можете видеть недостаток, что для того, чтобы ваши методы ссылались друг на друга и на ваши переменные, вы должны префиксировать их все именем вашего объекта. Если у вас есть подпространства, это становится еще хуже. К счастью, есть способы обойти это, но я объявляю их вне сферы этого ответ.

Сказав Все это, кое - что для вас, чтобы прочитать на (Google) является "выявление шаблон модуля" - поможет вам пойти немного больше OO (если это то, что вы хотите).

Действительно глубокий ответ на ваш вопрос можно найти здесь: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

Дальнейшее чтение: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth