O que faz (function ($) {}) (jQuery); significar?

299

Estou apenas começando a escrever plugins jQuery. Escrevi três plugins pequenos, mas simplesmente copiei a linha em todos os meus plugins sem realmente saber o que isso significa. Alguém pode me falar um pouco mais sobre isso? Talvez uma explicação seja útil algum dia ao escrever uma estrutura :)

O que isso faz? (Eu sei que estende o jQuery de alguma forma, mas há mais alguma coisa interessante para saber sobre isso)

(function($) {

})(jQuery);

Qual é a diferença entre as duas maneiras a seguir de escrever um plugin:

Tipo 1:

(function($) {
    $.fn.jPluginName = {

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

Tipo 2:

(function($) {
    $.jPluginName = {

        }
})(jQuery);

Tipo 3:

(function($){

    //Attach this new method to jQuery
    $.fn.extend({ 

        var defaults = {  
        }  

        var options =  $.extend(defaults, options);  

        //This is where you write your plugin's name
        pluginname: function() {

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

Eu poderia estar longe daqui e talvez tudo signifique a mesma coisa. Estou confuso. Em alguns casos, isso não parece estar funcionando em um plug-in que eu estava escrevendo usando o Tipo 1. Até agora, o Tipo 3 parece ser o mais elegante para mim, mas eu gostaria de saber sobre os outros também.

lenda
fonte
22
É hora de dormir aqui, mas apenas para iniciantes, (function($) { })(jQuery);agrupa o código para que $fique jQuerydentro desse fechamento, mesmo que $signifique algo fora dele, geralmente como resultado, $.noConflict()por exemplo. Isso garante que seu plug-in funcione, independentemente de ser $ === jQuery :) :)
Nick Craver
3
Sobre (function($) { })(jQuery)você disse: "Eu sei que isso estende o jQuery de alguma forma [...]". Claramente você não sabe, pois sua afirmação é 100% falsa. A propósito, pode ser enganoso para futuros leitores. Dê uma olhada no seguinte: stackoverflow.com/a/32550649/1636522 .
leaf
Estendendo-se aos comentários de @ NickCraver, o jquery-ui-1.7.2.custom.min.js usa isso por exemplo: jQuery.ui || (função (c) {vari = c.fn.remove, d = c.browser. mozilla ........}) (jQuery) ;. Eu sei que é uma versão antiga da interface do usuário do jQuery com código obsoleto, mas o objetivo é mostrar como, nesse caso, eles estão usando "c" em vez de "$".
Jaime Montoya

Respostas:

234

Em primeiro lugar, um bloco de código que se parece (function(){})()é apenas uma função que é executada no local. Vamos dividir um pouco.

1. (
2.    function(){}
3. )
4. ()

A linha 2 é uma função simples, entre parênteses, para informar ao tempo de execução que retorne a função ao escopo pai. Uma vez retornada, a função é executada usando a linha 4, talvez a leitura dessas etapas ajude

1. function(){ .. }
2. (1)
3. 2()

Você pode ver que 1 é a declaração, 2 está retornando a função e 3 está apenas executando a função.

Um exemplo de como seria usado.

(function(doc){

   doc.location = '/';

})(document);//This is passed into the function above

Quanto às outras perguntas sobre os plugins:

Tipo 1: Este não é realmente um plugin, é um objeto passado como uma função, pois os plugins tendem a ser funções.

Tipo 2: novamente não é um plug-in, pois não estende o $.fn objeto. É apenas uma extensão do núcleo do jQuery, embora o resultado seja o mesmo. Isto é, se você deseja adicionar funções de deslocamento, como toArray e assim por diante.

Tipo 3: este é o melhor método para adicionar um plug-in, o protótipo estendido do jQuery pega um objeto com o nome e a função do seu plug-in e o adiciona à biblioteca de plugins para você.

RobertPitt
fonte
2
se você ler a pergunta original, o OP especificará três métodos para escrever encerramentos, ele nomeou esses métodos como tipo {1,2,3}. Estou me referindo às áreas da pergunta com uma resposta.
RobertPitt
1
(function () {}) significa retorna a função interna? O que exatamente o "()" significa?
Jaskey 02/02
Eu gosto do primeiro exemplo, mas o segundo, usando referências de número de linha (que não é um recurso js), não é claro.
Samy Bencherif
1
Isso se chama Expressão de Função Invocada Imediatamente (IIFE): benalman.com/news/2010/11/…
Andres Rojas
1
Tenho muitos problemas para entender o parêntese externo de ( function(){} ): O que é isso exatamente? Não posso apenas escrever function(){}()?
TMOTTM 17/08/19
127

No nível mais básico, algo do formulário (function(){...})()é uma literal de função que é executada imediatamente. O que isso significa é que você definiu uma função e a está chamando imediatamente.

Este formulário é útil para ocultar e encapsular informações, pois qualquer coisa que você definir dentro dessa função permanecerá local para essa função e inacessível a partir do mundo exterior (a menos que você a exponha especificamente - geralmente por meio de um objeto literal retornado).

Uma variação desse formulário básico é o que você vê nos plug-ins do jQuery (ou neste padrão de módulo em geral). Conseqüentemente:

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

O que significa que você está passando uma referência ao jQueryobjeto real , mas é conhecido como $dentro do escopo da função literal.

O tipo 1 não é realmente um plugin. Você está simplesmente atribuindo um literal de objeto ajQuery.fn . Normalmente, você atribui uma função, jQuery.fnpois os plug-ins geralmente são apenas funções.

O tipo 2 é semelhante ao tipo 1; você realmente não está criando um plugin aqui. Você está simplesmente adicionando um objeto literal a jQuery.fn.

O tipo 3 é um plug-in, mas não é a melhor ou a maneira mais fácil de criar um.

Para entender mais sobre isso, dê uma olhada nesta pergunta e resposta semelhante . Além disso, esta página apresenta alguns detalhes sobre a criação de plugins.

Vivin Paliath
fonte
1
Não tenho certeza de como o Tipo 3 está estendendo o núcleo. É uma maneira perfeitamente válida de criar um plug-in, pois você está estendendo o protótipo. Embora um pouco desnecessário.
tbranyen
1
Meu mal - eu deveria ter sido mais claro. Eu estava com pressa e você está correto.
Vivin Paliath
32

Uma ajudinha:

// an anonymous function
  
(function () { console.log('allo') });

// a self invoked anonymous function

(function () { console.log('allo') })();
  
// a self invoked anonymous function with a parameter called "$"
  
var jQuery = 'I\'m not jQuery.';

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

folha
fonte
21

Apenas pequena adição à explicação

Essa estrutura (function() {})();é denominada IIFE (Expressão de Função Imediatamente Invocada) e será executada imediatamente, quando o intérprete atingir essa linha. Então, quando você estiver escrevendo estas linhas:

(function($) {
  // do something
})(jQuery);

isto significa que o intérprete chamará a função imediatamente e passará jQuerycomo um parâmetro, que será usado dentro da função como $.

Suicídio Comercial
fonte
12

Na verdade, este exemplo me ajudou a entender o que (function($) {})(jQuery);significa.

Considere isto:

// Clousure declaration (aka anonymous function)
var f = function(x) { return x*x; };
// And use of it
console.log( f(2) ); // Gives: 4

// An inline version (immediately invoked)
console.log( (function(x) { return x*x; })(2) ); // Gives: 4

E agora considere isso:

  • jQuery é uma variável que contém o objeto jQuery.
  • $é um nome de variável como qualquer outro ( a, $b,a$b etc.) e que não tem nenhum significado especial como em PHP.

Sabendo que podemos dar uma outra olhada no nosso exemplo:

var $f = function($) { return $*$; };
var jQuery = 2;
console.log( $f(jQuery) ); // Gives: 4

// An inline version (immediately invoked)
console.log( (function($) { return $*$; })(jQuery) ); // Gives: 4
Krzysztof Przygoda
fonte
Para mim, esta é a melhor resposta. claro e tão simples
Saleh
11

Tipo 3, para funcionar, seria assim:

(function($){
    //Attach this new method to jQuery
    $.fn.extend({     
        //This is where you write your plugin's name
        'pluginname': function(_options) {
            // Put defaults inline, no need for another variable...
            var options =  $.extend({
                'defaults': "go here..."
            }, _options);

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

Não tenho certeza por que alguém usaria estender apenas a configuração direta da propriedade no protótipo jQuery, está fazendo exatamente a mesma coisa apenas em mais operações e mais desordem.

tbranyen
fonte