2011-11-22 32 views
7

Estoy muy familiarizado con las funciones de autoejecución al trabajar con jQuery.JavaScript Funciones autoejecutables: ¿cuál es la diferencia?

(function($) { /* do stuff */ })(jQuery); 

Hoy estaba leyendo la fuente Backbone.js y se dio cuenta de que lo hacen:

(function() { /* do stuff */ }).call(this); 

Es esto lograr lo mismo? ¿Las siguientes 2 líneas de código harían lo mismo?

(function($) { /* do stuff */ })(jQuery); 
(function($) { /* do stuff */ }).call(jQuery); 

Respuesta

12

La primera forma está pasando en un parámetro, mientras que la segunda forma está estableciendo lo que se refiere esto a dentro de la función de ejecución. Ellos son diferentes.

(function(x){ console.log(this,x); })(jQuery); 
//--> [window object] 
//--> [jQuery object] 

(function(x){ console.log(this,x); }).call(jQuery); 
//--> [jQuery object] 
//--> undefined 

(function(x){ console.log(this,x); }).call(jQuery, jQuery); 
//--> [jQuery object] 
//--> [jQuery object] 

Para obtener más información, consulte Function.prototype.call y Function.prototype.apply.

Aquí hay un caso en el que es posible que desee utilizar el call técnica:

v = 'oh noes!' 
var o = { 
    v : 42, 
    f : function(){ 
    console.log(this.v); 
    (function(){ console.log(this.v) })(); 
    } 
}; 
o.f(); 
// --> 42 
// --> 'oh noes!' 

sin ajustar el valor de this través call(), la función de auto-llamada se invoca en el ámbito de la Global (ventana) , no el objeto actual.

+1

aunque si fuera 'call (jQuery, jQuery)' establecería ambos. – zzzzBov

+0

@Phrogz Gracias. Lo entiendo. – modernzombie

+0

@zzzzBov ambos serían [jQuery objeto], ¿correcto? – modernzombie

3

En su caso:

(function() { /* do stuff */ }).call(this); 

... están asegurándose de que la función se llama con un valor específico para this (por ejemplo, this dentro de la función será el mismo que this fuera de la función).

En su caso:

(function($) { /* do stuff */ })(jQuery); 

... this dentro de su función será el objeto global, ya que hemos llamado sin hacer nada que establece this, y así this por defecto en el objeto global (window, en los navegadores).

En JavaScript, this se establece completamente por la forma en que se llama a una función. Hay dos formas principales:

  1. Llamando a la función como parte de la expresión que la recupera de una propiedad del objeto, p.

    obj.foo(); // Or `obj["foo"](); 
    

    En ese caso, dentro de la llamada a foo, this se referirá a obj.

  2. Al llamar a la función a través de su base de call o apply métodos:

    var obj = {name: "Fred"}; 
    function foo(salutation, punctuation) { 
        alert(salutation + " " + this.name + punctuation); 
    } 
    foo.call(obj, "Hi", "!"); // alerts "Hi Fred!" 
    foo.apply(obj, ["Hi", "!"]); // Also alerts "Hi Fred!" 
    

    La única diferencia entre call y apply es la forma de especificar argumentos para pasar a la función que está llamando: Con call , simplemente los enumera como argumentos discretos siguiendo el valor this que desea; con apply, los proporciona como una matriz.

+2

Desearía poder obtener +2 o +3 para obtener una gran información. – Phrogz

-2

.call pone la función en un ámbito de cierre.

Así que si usted hizo esto:

(function($) { /* do stuff */ }).call(jQuery); 

$ habría undefined

+1

-1 para terminología confusa/incorrecta; 'llamada' no tiene nada que ver con cierres. – Phrogz

1

La primera pasa jQuery como el parámetro $. El segundo hace jQuery la variable 'this' dentro de la función.

Cuestiones relacionadas