2009-12-29 7 views

Répondre

24

L'utilisation de apply est liée au contexte de la fonction (mot-clé this) et à la transmission d'arguments.

D'abord, je pense que vous devriez savoir dans quels cas le mot-clé this est implicitement ensemble:

1- Lorsqu'une fonction est appelée comme méthode (la fonction est invoquée en tant que membre d'un objet):

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

2- Un appel de fonction normale:

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

3- Lorsque le new opérateur est utilisé:

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

est ici quand apply et call viennent, ces méthodes vous permettent de définir explicitement le contexte lorsque vous invoquez une fonction, par exemple .:

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

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

Dans le code ci-dessus , lorsque la fonction test est appelée en définissant le mot clé this à une chaîne ('Hello') et en transmettant l'argument a (' world.').

deux, call et apply changement le contexte de la fonction d'exécution (le mot-clé this) dans la fonction appelée, mais la différence entre eux est que, avec apply, vous pouvez envoyer un tableau ou un objet Array comme en les arguments de la fonction à exécuter, ce qui est extrêmement utile, par exemple:

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 

Cela peut éviter certains très aki, mauvais (et communs) eval appels tels que:

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

Un autre exemple, les méthodes et Math.maxMath.min, ces méthodes peuvent recevoir un nombre arbitraire d'arguments tels que:

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

Mais si vous avez un tableau de nombres?

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

Notez également que lorsque null ou undefined est utilisé comme argument this avec call ou apply, l'objet this fera référence à l'objet global (similaire au cas n ° 2, l'invocation de la fonction normale).

Pour l'exemple Math.max, le contexte est pas vraiment pertinent, car ils sont comme « statiques » méthodes, le mot-clé this n'est pas utilisé en interne ...

+3

+1 Très agréable! ---- –

+0

Ah je pense que je l'ai maintenant. Le point entier que j'ai manqué était «la valeur de ceci est fournie en tant que premiers paramètres». Maintenant, il est logique de vouloir différencier la méthode d'application en une sorte d'invocation distincte. Alors, quel est le diff. entre appel et appliquer des mots-clés alors? – Priyank

+0

@cms +1 parfait pour imprimer! –

0

Je ne suis pas au courant d'une conception modèles nommés The Apply Pattern, donc je ne pense pas vraiment que cela soit lié aux modèles de conception. Cependant, il existe une méthode d'application des objets de fonction en javascript (avec la méthode d'appel correspondante), donc je vais les expliquer.

Les méthodes apply et call permettent essentiellement à un objet de «voler» une méthode à un autre objet. Vous voyez, en javascript, les méthodes sont liées très très tard: au moment de l'invocation. Ce n'est que lorsqu'une méthode est appelée que la valeur 'this' est résolue. Dans un appel de méthode normale:

some_object.do_something(); 

le mot-clé dans 'this' do_something fait référence à some_object. Appliquer et appeler vous permet de réattribuer 'this'. Par exemple:

some_object.do_something.apply(another_object); 

le mot-clé dans 'this' do_something se réfère maintenant à another_object. Vous appelez donc la méthode do_something appartenant à some_object sur another_object. Maintenant, c'est intéressant et tout, mais pourquoi quelqu'un voudrait-il le faire? Voici un exemple concret des raisons pour lesquelles cela est utile:

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

Il y a un autre cas d'utilisation pour appliquer ce qui résulte de la différence entre la façon dont appliquer et appeler des œuvres. Si vous avez tous vos arguments dans un tableau et la fonction prend des arguments individuels, vous pouvez utiliser appliquer pour passer le tableau et ont la fonction voir le contenu du tableau comme arguments individuels:

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

Vous pouvez également utiliser l'appel/demander l'héritage.

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 
}; 

Avis Client.call (this, id); Ce Client exécute en utilisant l'instance this qu'un new WebClient créerait. Ainsi, lorsque

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

sont exécutées à l'intérieur Client l'instance WebClient est attribué obtenir ces propriétés.

Questions connexes