Включение внешнего скрипта jQuery - PullRequest
3 голосов
/ 10 июня 2011

У меня есть внешний файл JavaScript, который будет использоваться на страницах с множеством других сценариев.Мой сценарий включает в себя много jQuery, который прослушивает события, и по дизайну я объявил много глобальных переменных.Я читал лучшие практические статьи, и много говорится о «загрязнении глобального пространства имен» и непреднамеренном взаимодействии сценариев.

Какой лучший способ заключить (инкапсулировать?) Мой файл JavaScript так, чтобы:

  • Я все еще могу получить доступ к некоторым переменным за пределами корпуса
  • Слушатели событий jQuery будут работать правильно

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

Я нашел стили вложения для обычного JavaScript, но затрудняет ли это использование jQuery?

Ответы [ 6 ]

1 голос
/ 10 июня 2011

Обычно все сводится к инкапсуляции ваших объектов в «пространство имен». Я использую кавычки, потому что этот термин не является официальной семантикой в ​​JavaScript, а скорее достигается путем инкапсуляции базовых объектов.

Есть несколько способов сделать это, и в конечном итоге все сводится к личным предпочтениям.

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

var SomeName = {
    alpha: 1,
    beta: {a: 1, b: 2},
    gamma: function(){ 
        SomeName.alpha += 1;
    }
}

В этом случае только SomeName находится в глобальном пространстве имен. Единственным недостатком этого подхода является то, что все внутри пространства имен является общедоступным, и вы должны использовать полное пространство имен для ссылки на объект, вместо использования «this» - например, в SomeName.gamma мы должны использовать SomeName.alpha для ссылки на содержимое альфа.

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

var SomeName = (function(){
   var self = this;
   var privateVar = 1;
   var privateFunc = function() { };   

   this.publicVar = 2;
   this.publicFunc = function(){
       console.log(privateVar);
       console.log(this.publicVar); // if called via SomeName.publicFunc

       setTimeout(function(){ 
           console.log(self.publicVar);
           console.log(privateVar);
       }, 1000);
   };
}();

Другим преимуществом этого подхода является то, что он позволяет вам защитить глобальные переменные, которые хотите использовать. Например, если вы используете jQuery И другую библиотеку, которая создает переменную $, вы всегда можете убедиться, что ссылаетесь на jQuery при использовании $ таким способом:

var SomeName = (function($){
    console.log($('div'));
})(jQuery);
1 голос
/ 10 июня 2011

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

var myStuff = (function() {

   var globalVar1;
   var globalVar2;
   var privateVar1;

   function myFunction() {
     ...
   }

   function myPrivateFunction() {
     ...
   }

   return {
      var1: globalVar1,
      var2: globalVar2,
      myFunction: myFunction
   };

})();

Теперь вы можете получить доступ к myStuff.var1 и myStuff.myFunction().

1 голос
/ 10 июня 2011

Один из методов заключается в использовании пространства имен следующим образом:

var MyNamespace = {
    doSomething: function() {},
    reactToEvent: function() {},
    counter: 0
}

Вам просто нужно обратиться к функциям или переменной, используя пространство имен: MyNamespace.reactToEvent. Это отлично работает для отделения того, что вы обычно имеете в window (где все противостояние).

0 голосов
/ 10 июня 2011

Это обычная практика для плагинов jQuery по тем же причинам, которые вы упомянули:

;(function ($) {

    /* ... your code comes here ... */

})(jQuery);

Это немедленная функция.Если вы объявите свои «глобальные» переменные внутри, они будут локальными для этого замыкания (все еще «глобальными» для кода, который вы создаете внутри).Здесь также будут работать ваши слушатели событий, и вы все равно сможете получать реальные глобальные переменные.

0 голосов
/ 10 июня 2011

Я только начал использовать RequireJS и теперь стал одержим им.

Это в основном система управления зависимостями в модульном формате JavaScript. Тем самым вы можете практически исключить присоединение чего-либо к глобальному пространству имен.

Что приятно, вы ссылаетесь только на один скрипт на своей странице require.js, а затем сообщаете ему, какой скрипт запустить первым. Оттуда все это волшебство ...

Вот пример сценария реализации:

require([
   //dependencies
   'lib/jquery-1.6.1'
], function($) {
   //You'll get access to jQuery locally rather than globally via $


});

Прочтите API RequireJS и посмотрите, подходит ли вам это. Я сейчас пишу все свои сценарии. Это здорово, потому что в начале каждого скрипта вы точно знаете, какие у вас зависимости похожи на серверные языки - Java или C #.

0 голосов
/ 10 июня 2011

Два способа инкапсулировать или ограничить загрязнение пространства имен

1) Создайте один глобальный var и вставьте в него все, что вам нужно.

var g = {};
g.somevar = "val";
g.someothervar = "val2";
g.method1 = function() 
{
   // muck with somevar
   g.somevar = "something else";
};

2) Для встроенных сценариев рассмотрите возможность ограничения объема вызываемых функций.

<script>
(  
   function(window)
   {
      // do stuff with g.somevar
      if(g.somevar=="secret base")
        g.docrazystuff();      

   }
)();  // call function(window) then allow function(window) to be GC'd as it's out of scope now
</script>
...