Les fonctions d'appel et d'application sont rarement utilisées dans certaines opérations JavaScript simples. Dans d'autres grandes opérations, telles que le développement d'applications Web, ces deux fonctions peuvent être rencontrées fréquemment dans le développement du cadre JS. Il y a aussi beaucoup d'informations sur les explications de ces deux fonctions, mais je pense que beaucoup d'informations sont écrites ou très similaires, et manque d'explications terre-à-terre. Ensuite, j'essaie d'analyser et d'expliquer ces deux fonctions avec une idée plus claire et plus simple.
La copie de code est la suivante:
Nous pouvons considérer Call () et appliquer () comme des méthodes d'un certain objet, et appeler indirectement les fonctions en appelant l'implémentation de la méthode. Le premier argument d'appel () et applique () est l'objet parent pour appeler la fonction. C'est le contexte d'appel, et une référence est obtenue à travers cela dans le corps de la fonction. Pour appeler la fonction f () sur la méthode de l'objet O, vous pouvez utiliser Call () et appliquer () comme ceci: F.Call (o) F.Apply (o). [1]
Analysons d'abord l'appel. Voici l'explication de la fonction d'appel par ECMascript 3rd Edition [2]: Lorsque la méthode d'appel est appelée par un objet fonction (func.Call (0)), un paramètre nécessaire et plusieurs paramètres non essentiels doivent être transmis. Son processus d'exécution est le suivant:
A, si l'objet appelant l'appel n'est pas en cours d'exécution, une erreur TypeError est lancée.
B, définissez la liste des paramètres sur vide
C, si la méthode appelée passe plus d'un paramètre, alors insérez Arg1, Arg2 ... dans la liste des paramètres à son tour
D, renvoie le résultat de l'appel de l'appel, remplacez-le dans la fonction d'appel (FUNC) par le paramètre passé 1 et traitez la liste des paramètres passés comme le paramètre de cette fonction.
En fait, la fonction d'appel est le prototype de l'objet de fonction. C'est-à-dire la fonction que les appels doivent également être une fonction. Lorsque vous appelez cet appel, remplacez-le simplement dans la fonction qui appelle l'appel par l'objet passé. Voici un exemple:
<Script> Fonction C1 () {this.name = 'Zhang San'; this.age = '24 '; this.sayName = function () {console.log ("voici la classe C1, mon nom est:" + this.name + "mon âge est" + this.age); }} fonction c2 () {this.name = 'li si'; this.age = '25 '; } var c1 = new C1 (); var c2 = nouveau c2 (); c1.sayName (); c1.sayname.call (c2); </cript>Résultats de l'exécution:
Voici la catégorie C1, je m'appelle: Zhang San mon âge a 24 ans
Voici la catégorie C1, je m'appelle: Li si mon âge a 25 ans
Dans le code ci-dessus, deux classes sont déclarées, C1 et C2. C1 a deux propriétés, une méthode et C2 a également deux propriétés identiques à C1. Après l'instanciation, C1.SayName () imprime les propriétés réelles, mais C1.SayName.Call (C2) imprime les propriétés de C2, pourquoi est-ce? Parce que SayName () est une fonction et il y a cela dans le corps de la fonction, lorsque l'appel sera exécuté, cela sera remplacé par C2, de sorte que l'attribut de C2 sera finalement imprimé.
La différence entre l'application et l'appel réside dans le passage des paramètres facultatifs. Tous les paramètres facultatifs de l'application sont stockés dans un tableau, car un paramètre est entré, tandis que l'appel est transmis dans plusieurs paramètres.
Alors, quelles sont les applications des fonctions d'application et d'appel? La première consiste à trouver le plus grand élément du tableau numérique du réseau. Vous pouvez utiliser directement math.max.apply (null, array). L'autre consiste à utiliser Appliquer et appeler pour hériter, comme suit:
<Script> fonction humain (nom, sexe) {this.name = name; this.sex = sexe; this.walk = function () {console.log ('je marche'); }} fonction child () {humain.call (this, "xiao ming", "mâle") this.paly = function () {console.log ('j'aime jouer beaucoup'); } this.intruduce = function () {console.log ('bonjour tout le monde, i' + this.name); }} var jinp = new humain ('jack', 'mâle'); var xiaoping = new child (); xiaoping.walk (); xiaoping.paly (); xiaoping.intruducus (); </cript>Résultats de l'exécution:
Je marche
J'aime beaucoup jouer
Bonjour à tous, je suis xiao ming
La fonction similaire pour appeler () et appliquer () est bind (), qui est une nouvelle méthode ajoutée dans ECMAScript 5, mais elle peut être facilement simulée dans ECMAScript 3. La fonction Bind est également la méthode de la fonction.Prototype dans JavaScript. Le contenu principal de cette méthode est de lier la fonction à un objet. Lorsque la méthode bind () est liée à la fonction f () et qu'un objet O est passé sous forme de paramètre, cette méthode renvoie une nouvelle fonction et sera appelée comme méthode de o. Tout argument transmis à la nouvelle fonction sera transmis à la fonction d'origine. comme suit:
<Script> Fonction Introduction (country, hobby) {return "Bonjour à tous, mon nom est" + this.name + ", cette année" + this.age + "année, de" + country + ", comme" + hobby; } var xiaoMing = {name: "xiao ming", âge: 20} var jieshao = introdu.bind (xiaoMing); Console.log (Jieshao ("Chine", "Playing Ball")); </cript>Résultats de l'exécution:
Bonjour à tous, je m'appelle Xiao Ming, j'ai 20 ans, de Chine, j'aime jouer au basket
L'exemple ci-dessus est équivalent à:
<Script> Fonction Introduction (country, hobby) {return "Bonjour à tous, mon nom est" + this.name + ", cette année" + this.age + "année, de" + country + ", comme" + hobby; } var XiaoMing = {name: "XiaoMing", âge: 20} console.log (introdu.Apply (xiaoMing, ["Chine", "Play"])); // ou la console.log (introdu.call (xiaoMing, "China", "Play")); </cript>Il convient de noter que dans le mode strict d'Ecmascript 5, le premier réel argument de Call () et applique () deviendra cette valeur, même si l'argument réel est la valeur d'origine ou même nul ou indéfinie. En mode ECMAScript 3 et non-stricte, le Null et non défini passés seront remplacés par la confrontation globale, tandis que d'autres valeurs d'origine seront remplacées par l'objet de wrapper correspondant.
Références
[1], Guide JavaScript faisant autorité, 6e édition, page 189
[2], function.prototype.call (thisarg [, arg1 [, arg2,…]])
[3], function.prototype.apply (thisarg, argarray)