Eu gostaria de entender a sintaxe do plugin jQuery

89

O site jQuery lista a sintaxe básica do plugin para jQuery como esta:

(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 );

Eu só gostaria de entender o que está acontecendo lá do ponto de vista do Javascript, porque não parece que segue qualquer sintaxe que já vi o JS fazer antes. Então aqui está minha lista de perguntas:

  1. Se você substituir function ($) ... por uma variável, diga "the_function", a sintaxe será semelhante a esta:

     (the_function)( jQuery );

    O que é "(jQuery);" fazendo? Os parênteses em torno da função_ são realmente necessários? Por que eles estão lá? Existe outro código que você pode fornecer que seja semelhante?

  2. Ele começa com a função ($). Então está criando uma função, que pelo que eu sei nunca será executada, com o parâmetro de $, que já está definido? O que está acontecendo lá?

Obrigado pela ajuda!

Ethan
fonte

Respostas:

130
function(x){ 
    x...
}

é apenas uma função sem nome, que recebe um argumento, "x", e faz coisas com x.

Em vez de 'x', que é um nome de variável comum, você pode usar $, que é um nome de variável menos comum, mas ainda válido.

function($){ 
    $...
}

Vou colocá-lo entre parênteses para garantir que ele seja analisado como uma expressão:

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

Para chamar uma função, coloque () depois dela com uma lista de argumentos. Por exemplo, se quiséssemos chamar essa função passando 3 para o valor de $, faríamos isso:

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

Só por diversão, vamos chamar esta função e passar jQuery como uma variável:

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

Isso cria uma nova função que recebe um argumento e, em seguida, chama essa função, passando jQuery como o valor.

PORQUE?

  • Porque escrever jQuery toda vez que você deseja fazer algo com jQuery é entediante.

POR QUE NÃO ESCREVER $ = jQuery?

  • Porque outra pessoa pode ter definido $ para significar outra coisa. Isso garante que quaisquer outros significados de $ sejam obscurecidos por este.
Joel Spolsky
fonte
20
É claro, mas está faltando uma elaboração sobre a necessidade de orientar o analisador para analisar a definição da função como uma expressão e não uma instrução . É para isso que servem os parênteses extras .
Pointy de
16
(function(){})()é conhecido como IIFE (Immediately Invoked Function Expression) . Deixá-lo ser conhecido que você pode usar outros símbolos para forçar o analisador para tratar a função como uma expressão como +,!,-,~(e outros) como este: !function($){}(jQuery). E para se divertir ainda mais, você pode ~~+-!function($){}(jQuery):!
David Murdoch
(função ($, win, doc) {$ ....}) (jQuery, janela, documento); Eu acrescentaria isso também ... Me ajudou a entender melhor. nesta parte do código, jQuery ---> $; e janela ---> ganhar; em seguida, documente ---> doc ... :) obrigado ...
Haranadh
Eu encontrei um exemplo de código que IMHO não é coberto na lista acima: $ (function () {.....} (jQuery)); (Retirado daqui: docs.microsoft.com/en-us/aspnet/core/mvc/models/… ). Aqui, não entendo o uso de $. Não parece ser um seletor jQuery $ (...) ou uma sintaxe curta para o evento 'documento pronto', porque a função não retorna nada. Eu também não pareço ser um prefixo para tratar a função como uma expressão, porque está fora das chaves. Mais, a chamada de função é feita DENTRO das chaves, então estamos chamando declaração.
sich
35

(function( $ ){

})( jQuery );

Essa é uma função anônima autoexecutável que usa $como argumento para que você possa usar it ( $) em vez de jQuerydentro dessa função e sem medo de entrar em conflito com outras bibliotecas porque em outras bibliotecas também $tem um significado especial. Esse padrão é especialmente útil ao escrever plug-ins jQuery.

Você pode escrever qualquer caractere lá em vez de $também:

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

})(jQuery);

Aqui j, o jQuery será atualizado automaticamente, especificado no final (jQuery). Ou você pode deixar o argumento completamente de fora, mas então terá que usar jQuerytodas as palavras-chave ao invés de ainda $sem medo de colisão. Então, $está envolvido no argumento para abreviação de modo que você possa escrever em $vez de jQuerytudo dentro dessa função.

Se você olhar o código-fonte do jQuery, verá que tudo está entre:

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

Isso é como pode ser visto também uma função anônima autoexecutável com argumentos. Um argumento window(e undefined) é criado e mapeado com o windowobjeto global na parte inferior (window). Este é um padrão popular hoje em dia e tem pouco ganho de velocidade porque aqui windowserá analisado a partir do argumento, e não do windowobjeto global mapeado abaixo.


O $.fné objeto do jQuery onde você criar sua nova função (que é também um objeto) ou o próprio plug-in para que jQuery envolve seu plugin no seu $.fnobjeto e torná-lo disponível.


Curiosamente, eu tinha respondido a uma pergunta semelhante aqui:

Sintaxe da função de encerramento JavaScript / jQuery

Você também pode verificar este artigo para saber mais sobre as funções autoexecutáveis ​​que escrevi:

Funções de autoexecução Javascript

Sarfraz
fonte
Portanto, se eu tivesse um objeto chamado meu_objeto e fizesse isso: (function (mo) {mo.doSomething ()}) (meu_objeto), ele executaria meu_objeto.doSomething ()?
Ethan
3

A sintaxe básica do plug-in permite que você faça $referência ao jQuerycorpo do plug-in, independentemente da identificação de $no momento em que o plug-in é carregado. Isso evita conflitos de nomenclatura com outras bibliotecas, principalmente Prototype.

A sintaxe define uma função que aceita um parâmetro conhecido como $para que você possa se referir a ele como $no corpo da função e, em seguida, invoca imediatamente essa função, colocando jQuery-a como o argumento.

Isso também ajuda a não poluir o namespace global (portanto, declarar var myvar = 123;no corpo do plug-in não definirá repentinamente window.myvar), mas o principal propósito aparente é permitir que você use $onde $pode ter sido redefinido.

Steven
fonte
3

Você está lidando com uma função anônima de auto-invocação. É como uma "prática recomendada" envolver um plugin jQuery em tal função para ter certeza de que o $sinal está vinculado ao jQueryobjeto.

Exemplo:

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

Isso alertaria BARquando colocado em um <script>bloco. O parâmetro BARé passado para a função que chama a si mesma.

O mesmo princípio está acontecendo em seu código, o jQueryobjeto é passado para a função, então $irá se referir ao objeto jQuery com certeza.

Andy
fonte
1
Eu entendo tudo isso. O que eu quero saber é por que / como a sintaxe de colchetes funciona para criar uma função autoexecutável? Isso é apenas uma característica da linguagem? Como funciona?
carne
2

O jQuery no final passa a si mesmo (jQuery) para a função, para que você possa usar o símbolo $ dentro do seu plugin. Você também poderia fazer

(function(foo){

  foo.fn.myPlugin = function() {


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


    });

  };
})( jQuery );
harpax
fonte
2

Para encontrar uma explicação clara deste e de outros truques modernos e práticas comuns do javascript, recomendo a leitura do Javascript Garden.

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

É especialmente útil, porque muitos desses padrões são amplamente usados ​​em muitas bibliotecas, mas não são realmente explicados.

OlliM
fonte
2

As outras respostas aqui são ótimas, mas há um ponto importante que não foi abordado. Você diz:

Então está criando uma função, que pelo que eu sei nunca será executada, com o parâmetro de $, que já está definido?

Não há garantia de que a variável global $esteja disponível . Por padrão, o jQuery cria duas variáveis ​​no escopo global: $e jQuery(onde os dois são apelidos para o mesmo objeto). No entanto, o jQuery também pode ser executado no modo noConflict :

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

Quando você chama jQuery.noConflict(), a variável global $é definida de volta para o que era antes de a biblioteca jQuery ser incluída. Isso permite que o jQuery seja usado com outras bibliotecas Javascript que também são usadas $como uma variável global.

Se você escreveu um plug-in que dependia de $ser um alias para jQuery, seu plug-in não funcionaria para usuários executando no modo noConflict.

Como outros já explicaram, o código que você postou cria uma função anônima que é chamada imediatamente. A variável global jQueryé então passada para esta função anônima, que é seguramente alias como a variável local$ dentro da função.

Kip
fonte