2009-12-29 17 views

Respuesta

24

El uso de apply se relaciona con el contexto de la función (la palabra clave this) y el argumento que pasa.

En primer lugar, creo que usted debe saber en qué casos la palabra clave es thisimplícitamente conjunto:

1- Cuando se invoca una función como un método (la función es invocada como miembro de un objeto):

obj.method(); // 'this' inside method will refer to obj 

2- una llamada normal función:

myFunction(); // 'this' inside the function will refer to the Global object 
// or 
(function() {})(); 

3- Cuando el new operador se utiliza:

var obj = new MyObj(); // this will refer to a newly created object. 

Aquí es cuando apply y call vienen, estos métodos permiten configurar de forma explícita el contexto cuando se invoca una función, por ejemplo .:

function test(a) { 
    alert(this + a); 
} 

test.call('Hello', ' world!'); 

En el código anterior , cuando la función test se llama establecer la palabra clave this en una cadena ('Hello') y pasa el argumento a (' world.').

Ambos, call y apply cambio el contexto de la función de ejecutar (el this palabra clave) dentro de la función llamada, pero el diferencia entre ellos es que con apply, puede enviar una matriz o un objeto Array similar a como se los argumentos de la función a ejecutar, que es extremadamente útil, por ejemplo:

function sum() { 
    var result = 0; 
    for (var i = 0; i < arguments.length; i++) { 
    result += arguments[i]; 
    } 
    return result; 
} 

var args = [1,2,3]; 
sum.apply(null, args); // will return 6 

que pueden evitar algunos muy hacky, malas (y comunes) eval llamadas como:

eval('sum(' + args.join() +')'); 

Otro ejemplo, los métodos y Math.maxMath.min, esos métodos pueden recibir un número arbitrario de argumentos como:

var max = Math.max(2,4,6,8); // 8 

Pero lo que si usted tiene una serie de números?

var numbers = [2,4,6,8]; 
numbers.push(10); 
var max = Math.max.apply(null, numbers); // 10 

en cuenta también que cuando null o undefined se utiliza como el argumento this con call o apply, el objeto this se referirá al objeto global (similar al caso # 2, la función de invocación normal).

Para el ejemplo Math.max, el contexto no es realmente relevante, ya que son como métodos "estáticos", la palabra clave this no se utiliza internamente ...

+3

+1 ¡Muy bonito! ---- –

+0

Ah, creo que lo entiendo ahora. El punto que me perdí fue "el valor de esto se proporciona como los primeros parámetros". Ahora tiene sentido por qué nos gustaría diferenciar el método de aplicación como un tipo de invocación por separado. Entonces, ¿cuál es la diferencia. entre llamar y aplicar palabras clave, entonces? – Priyank

+0

@cms +1 ¡perfecto para imprimir! –

0

No estoy al tanto de cualquier diseño patrones llamados The Apply Pattern, así que realmente no creo que esto esté relacionado con los patrones de diseño. Sin embargo, hay un método de aplicación de objetos de función en javascript (junto con el método de llamada correspondiente), así que los explicaré.

Los métodos de solicitud y llamada básicamente permiten que un objeto "robe" un método de otro objeto. Verá, en JavaScript, los métodos están vinculados muy, pero muy tarde: en el momento de la invocación. Solo cuando se llama a un método se resuelve el valor de 'this'. En una llamada de método normal:

some_object.do_something(); 

la palabra clave 'this' en hacer_algo refiere a some_object. Aplicar y llamar le permite volver a asignar 'this'. Por ejemplo:

some_object.do_something.apply(another_object); 

la palabra clave 'this' en hacer_algo ahora se refiere a another_object. Entonces estás llamando al método do_something que pertenece a some_object en otro_objeto.

Ahora, esto es interesante y todo, pero ¿por qué alguien querría hacer esto? Aquí está un ejemplo concreto de por qué esto es útil:

// say you want to get some DIVs in the document, you can get all of them with: 
var some_divs = document.getElementsByTagName('DIV'); 

// say you want the third to fifth DIV in the document, some_divs looks like an 
// array so you might think you can slice it, but it's not. It's a collection 
// of elements that fakes being an array and doesn't implement the slice method. 

// No worries, we can steal the slice method from an array 
// and apply it to some_divs: 
var wanted_divs = [].slice.apply(some_divs,[2,5]); 

// Alternatively: 
var wanted_divs = [].slice.call(some_divs,2,5); 

Hay otro caso de uso para aplicar el cual es el resultado de la diferencia entre la forma de aplicar y llamar a las obras. Si usted tiene todos sus argumentos en una matriz y la función de espera argumentos individuales puede utilizar aplica a pasar la matriz y tienen la función de ver el contenido de la matriz como argumentos individuales:

function some_function (first,second) { 
    alert(first+second); 
} 
var argument_array = ['hello','world']; 
some_function.apply(null, argument_array); 
1

También puede utilizar la llamada/solicitar la herencia

function Client (id) { 
    this.id = id; 
    this.name = "Client" + id; 
} 

Client.prototype = { 
    constructor: Client 

    , toString: function() { 
     return this.name; 
    } 
}; 

function WebClient (id) { 
    Client.call (this, id); 
} 

WebClient.prototype = new Client(); 

WebClient.prototype.constructor = WebClient; 

WebClient.prototype.ping = function() { 
    // do stuff 
}; 

Aviso Client.call (this, id); Esto ejecuta Client utilizando la instancia this que un new WebClient crearía. Así, cuando

this.id = id; 
    this.name = "Client" + id; 

se ejecutan dentro de la instancia ClientWebClient se está asignado esas propiedades.

Cuestiones relacionadas