Я хотел бы понять синтаксис плагина jQuery

89

На сайте jQuery указан базовый синтаксис плагина для jQuery:

(function( $ ){    
  $.fn.myPlugin = function() {      
    // there's no need to do $(this) because
    // "this" is already a jquery object

    // $(this) would be the same as $($('#element'));

    this.fadeIn('normal', function(){    
      // the this keyword is a DOM element    
    });    
  };
})( jQuery );

Я просто хотел бы понять, что там происходит, с точки зрения Javascript, потому что не похоже, что он следует какому-либо синтаксису, который я видел раньше в JS. Итак, вот мой список вопросов:

  1. Если вы замените функцию ($) ... переменной, скажем "the_function", синтаксис будет выглядеть следующим образом:

     (the_function)( jQuery );
    

    Что такое "(jQuery);" делаешь? Действительно ли нужны круглые скобки вокруг the_function? Почему они там? Есть ли другой похожий фрагмент кода?

  2. Он начинается с функции ($). Итак, он создает функцию, которая, насколько я могу судить, никогда не будет запущена, с параметром $, который уже определен? Что там происходит?

Спасибо за помощь!

Итан
источник

Ответы:

130
function(x){ 
    x...
}

это просто функция без имени, которая принимает один аргумент «x» и выполняет действия с x.

Вместо «x», которое является обычным именем переменной, вы можете использовать $, менее распространенное имя переменной, но все же допустимое.

function($){ 
    $...
}

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

(function($){
    $....
})

Чтобы вызвать функцию, вы помещаете после нее () со списком аргументов. Например, если бы мы хотели вызвать эту функцию, передав 3 в качестве значения, $мы бы сделали это:

(function($){
    $...
})(3);

Просто ради удовольствия вызовем эту функцию и передадим jQuery в качестве переменной:

(function($){
     $....
})(jQuery);

Это создает новую функцию, которая принимает один аргумент, а затем вызывает эту функцию, передавая jQuery в качестве значения.

ЗАЧЕМ?

  • Потому что писать jQuery каждый раз, когда вы хотите что-то сделать с jQuery, утомительно.

ПОЧЕМУ ПРОСТО НЕ ПИШИТЕ $ = jQuery?

  • Потому что кто-то другой мог определить $ как нечто иное. Это гарантирует, что любое другое значение $ затеняется этим.
Джоэл Спольски
источник
20
Это ясно, но в нем отсутствует уточнение о необходимости направлять синтаксический анализатор на синтаксический анализ определения функции как выражения, а не оператора . Для этого нужны дополнительные круглые скобки.
Pointy
16
(function(){})()известен как IIFE (выражение немедленного вызова функции) . Пусть это будет известно , что вы можете использовать другие символы , чтобы заставить парсер рассматривать функцию как выражение , например , как +,!,-,~(и другие) , как это: !function($){}(jQuery). А для еще большего удовольствия вы можете ~~+-!function($){}(jQuery):!
Дэвид Мердок
(функция ($, победа, док) {$ ....}) (jQuery, окно, документ); Я бы тоже это добавил ... Это помогло мне лучше понять. в этом куске кода jQuery ---> $; и окно ---> выиграть; затем документ ---> док ... :) спасибо ...
Haranadh 03
Я столкнулся с образцом кода, который, по моему мнению, не охвачен в приведенном выше списке: $ (function () {.....} (jQuery)); (Взято отсюда: docs.microsoft.com/en-us/aspnet/core/mvc/models/… ). Здесь я не понимаю, как используется $. Это не похоже ни на селектор jQuery $ (...), ни на короткий синтаксис для события «документ готов», потому что функция ничего не возвращает. Я также не кажется префиксом для обработки функции как выражения, потому что он находится вне фигурных скобок. Более того, вызов функции выполняется ВНУТРИ фигурных скобок, поэтому мы вызываем объявление.
Сечь
35

(function( $ ){

})( jQuery );

Это самоисполняющаяся анонимная функция, которая использует $аргумент in, чтобы вы могли использовать it ( $) вместо jQueryвнутри этой функции, не опасаясь конфликта с другими библиотеками, потому что в других библиотеках тоже $есть особое значение. Этот шаблон особенно полезен при написании плагинов jQuery.

Вы можете написать там любой символ вместо $тоже:

(function(j){
  // can do something like 
  j.fn.function_name = function(x){};

})(jQuery);

Здесь jавтоматически догонит jQuery, указанный в конце (jQuery). Или вы можете полностью опустить аргумент, но тогда вам придется использовать jQueryключевое слово повсюду, а $не все еще опасаясь столкновения. Так $заключен в аргумент для краткости, чтобы вы могли писать $вместо jQueryвсего вокруг внутри этой функции.

Если вы даже посмотрите исходный код jQuery, вы увидите, что все заключено между ними:

(function( window, undefined ) {
  // jQuery code
})(window);

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


Это $.fnобъект jQuery, в котором вы создаете свою новую функцию (которая также является объектом) или сам плагин, так что jQuery оборачивает ваш плагин в свой $.fnобъект и делает его доступным.


Интересно, что здесь я ответил на аналогичный вопрос:

Синтаксис функции закрытия JavaScript / jQuery

Вы также можете прочитать эту статью, чтобы узнать больше о написанных мною самоисполняющихся функциях:

Самостоятельно выполняющиеся функции Javascript

Сарфраз
источник
Итак, если бы у меня был объект с именем my_object, и я сделал бы это: (function (mo) {mo.doSomething ()}) (my_object), тогда он запустил бы my_object.doSomething ()?
Итан
3

Базовый синтаксис плагина позволяет вам использовать $для ссылки jQueryв теле вашего плагина, независимо от идентификатора $во время загрузки плагина. Это предотвращает конфликты именования с другими библиотеками, особенно с Prototype.

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

Это также помогает не загрязнять глобальное пространство имен (поэтому объявление var myvar = 123;в теле вашего плагина не будет внезапно определять window.myvar), но основная мнимая цель - позволить вам использовать $where, $возможно, с тех пор было переопределено.

Стивен
источник
3

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

Пример:

(function(foo) {
    alert(foo);
}('BAR'));

Это будет предупреждать, BARкогда помещается в <script>блок. Параметр BARпередается функции, которая вызывает сама себя.

Тот же принцип реализуется в вашем коде, jQueryобъект передается функции, поэтому обязательно $будет ссылаться на объект jQuery.

Дженди
источник
1
Я все это понимаю. Я хочу знать, почему / как синтаксис скобок работает для создания самоисполняющейся функции? Это просто особенность языка? Как это работает?
плоть
2

JQuery в конце передает себя (jQuery) функции, так что вы можете использовать символ $ в своем плагине. Вы также могли бы сделать

(function(foo){

  foo.fn.myPlugin = function() {


    this.fadeIn('normal', function(){


    });

  };
})( jQuery );
гарпакс
источник
2

Чтобы найти четкое объяснение этого и других современных трюков и распространенных приемов javascript, я рекомендую прочитать Javascript Garden.

http://bonsaiden.github.com/JavaScript-Garden/

Это особенно полезно, потому что многие из этих шаблонов широко используются во многих библиотеках, но не совсем объяснены.

OlliM
источник
2

Другие ответы здесь прекрасны, но есть один важный момент, который не был рассмотрен. Ты говоришь:

Итак, он создает функцию, которая, насколько я могу судить, никогда не будет запущена, с параметром $, который уже определен?

Нет гарантии, что глобальная переменная $доступна . По умолчанию jQuery создает две переменные в глобальной области: $и jQuery(где две являются псевдонимами для одного и того же объекта). Однако jQuery также можно запустить в режиме noConflict :

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
  jQuery.noConflict();
</script>

Когда вы вызываете jQuery.noConflict(), глобальная переменная $возвращается к тому, что было до включения библиотеки jQuery. Это позволяет использовать jQuery с другими библиотеками Javascript, которые также используются $в качестве глобальной переменной.

Если вы написали плагин, который полагался на $псевдоним для jQuery, то ваш плагин не работал бы для пользователей, работающих в режиме noConflict.

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

Кип
источник