Советы программисту на промежуточном JavaScript для написания лучшего кода - PullRequest
5 голосов
/ 01 июля 2011

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

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

с функцией готовности документа jQuery для привязки различных событий к кнопкам в моем html и вызова моих функций в качестве обратных вызовов обработчика событий.

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

Ответы [ 5 ]

3 голосов
/ 01 июля 2011

Аналогичной версией версии Майкла и nnnnnn является

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

    },
    etc
};

YourApp - единственная глобальная переменная, и к ее свойствам можно получить доступ как

YourApp.function1();

или

YourApp.a;
3 голосов
/ 01 июля 2011

Мне нравится помещать содержимое каждого файла в анонимную функцию. Затем вы можете передать 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);
3 голосов
/ 01 июля 2011

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

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

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

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

2 голосов
/ 01 июля 2011

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

Относительно этого непосредственно к примеру, который вы привели с помощью a, b и т. Д .:

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

2 голосов
/ 01 июля 2011

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

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...