Aufrufen und Anwenden von Funktionen werden in einigen einfachen JavaScript -Operationen selten verwendet. In anderen großen Vorgängen wie der Entwicklung von Webanwendungen können diese beiden Funktionen häufig in der Entwicklung von JS Framework auftreten. Es gibt auch viele Informationen zu den Erklärungen dieser beiden Funktionen, aber ich denke, viele Informationen sind entweder geschrieben oder sehr ähnlich und es fehlen keine bodenständigen Erklärungen. Als nächstes versuche ich, diese beiden Funktionen mit einer klareren und einfacheren Idee zu analysieren und zu erklären.
Die Codekopie lautet wie folgt:
Wir können Call () und anwenden () als Methoden eines bestimmten Objekts betrachten und indirekt Funktionen aufrufen, indem wir die Methodenimplementierung aufrufen. Das erste Argument von Call () und Apply () ist das übergeordnete Objekt, um die Funktion aufzurufen. Es ist der aufrufende Kontext, und ein Hinweis darauf wird durch diese im Funktionskörper erhalten. Um die Funktion f () auf der Methode des Objekts O aufzurufen, können Sie CALL () und anwenden () wie folgt verwenden: F.Call (o) F.Apply (o). [1]
Lassen Sie uns zuerst den Anruf analysieren. Hier finden Sie die Erläuterung der Anruffunktion von ECMascript 3rd Edition [2]: Wenn die Aufrufmethode von einem Funktionsobjekt aufgerufen wird (Func.Call (0)), müssen ein notwendiger Parameter und mehrere nicht wesentliche Parameter übergeben werden. Sein Ausführungsprozess lautet wie folgt:
A, wenn das Objekt, das den Anruf aufruft, nicht ausgeführt wird, wird ein Type -ERROR -Fehler geworfen.
B, stellen Sie die Parameterliste auf leer ein
c, Wenn die aufgerufene Methode mehr als einen Parameter übergibt, fügen Sie Arg1, Arg2 ... in die Parameterliste ein
D, gibt das Ergebnis des Aufrufens des Anrufs zurück, ersetzen Sie diese in der Aufruffunktion (Func) durch den übergebenen Parameter 1 und behandeln Sie die übergebene Parameterliste als Parameter dieser Funktion.
Tatsächlich ist die Aufruffunktion der Prototyp des Funktionsobjekts. Das heißt, die Funktion, die Aufrufe aufrufen, muss ebenfalls eine Funktion sein. Wenn Sie diesen Anruf aufrufen, ersetzen Sie dies einfach in der Funktion, die den Anruf mit dem übergebenen Objekt aufruft. Hier ist ein Beispiel:
<Script> Funktion c1 () {this.name = 'zhang san'; this.age = '24 '; this.sayname = function () {console.log ("Hier ist C1 -Klasse, mein Name ist:"+this.name+"Mein Alter ist"+this.age); }} Funktion c2 () {this.name = 'li si'; this.age = '25 '; } var c1 = neuer c1 (); var c2 = neuer C2 (); c1.sayname (); c1.sayname.call (c2); </script>Ausführungsergebnisse:
Hier ist die C1 -Kategorie, mein Name ist: Zhang San mein Alter ist 24 Jahre alt
Hier ist die C1 -Kategorie, mein Name ist: li Si, mein Alter ist 25
Im obigen Code werden zwei Klassen deklariert, C1 und C2. C1 hat zwei Eigenschaften, eine Methode und C2 auch zwei Eigenschaften wie C1. Nach der Instanziierung druckt c1.sayname () die tatsächlichen Eigenschaften, aber c1.sayname.call (C2) die Eigenschaften von C2, warum ist das? Da SayName () eine Funktion ist und dies in der Funktionskörper ist, wird dies durch C2 ersetzt, wenn der Anruf ausgeführt wird, sodass das Attribut von C2 schließlich gedruckt wird.
Der Unterschied zwischen Anwendung und Anruf liegt in der Übergabe optionaler Parameter. Alle optionalen Parameter von Anwendungen werden in einem Array gespeichert, da ein Parameter eingegeben wird, während der Anruf in mehrere Parameter übergeben wird.
Was sind die Anwendungen von Bewerben und Anruffunktionen? Das erste besteht darin, das größte Element im numerischen Array im Netzwerk zu finden. Sie können Math.max.Apply (Null, Array) direkt verwenden. Die andere ist, wie folgt zu verwenden und aufzurufen, wie folgt:
<Script> Funktion Human (Name, Sex) {this.name = name; this.sex = sex; this.walk = function () {console.log ('Ich gehe'); }} function child () {human.call (this, "xiao ming", "männlich") this.paly = function () {console.log ('Ich spiele gerne sehr viel'); } this.inTruruduce = function () {console.log ('Hallo allerseits, i'+this.name); }} var jinp = new Human ('Jack', 'männlich'); var xiaoping = new Child (); xiaoping.walk (); xiaoping.paly (); Xiaoping.Intruduce (); </script>Ausführungsergebnisse:
Ich gehe
Ich spiele gerne sehr viel
Hallo allerseits, ich bin Xiao Ming
Die ähnliche Funktion wie call () und apply () ist bind (), eine neue Methode, die in ECMascript 5 hinzugefügt wurde, kann jedoch in ECMascript 3 leicht simuliert werden. Die Bindungsfunktion ist auch die Funktion.Prototyp -Methode in JavaScript. Der Hauptinhalt dieser Methode besteht darin, die Funktion an ein Objekt zu binden. Wenn die Methode Bind () an die Funktion f () gebunden ist und ein Objekt O als Parameter übergeben wird, gibt diese Methode eine neue Funktion zurück und wird als Methode von o aufgerufen. Alle an die neuen Funktion übergebenen Argumente werden an die ursprüngliche Funktion übergeben. wie folgt:
<Script> Funktion Einführung (Country, Hobby) {return "Hallo allerseits, mein Name ist"+this.name+", dieses Jahr"+this.age+"Jahr, aus"+Country+", wie"+Hobby; } var xiaoming = {name: "xiao ming", Alter: 20} var jieshao = infize.bind (xiaoming); console.log (jieshao ("China", "Ball spielen"); </script>Ausführungsergebnisse:
Hallo allerseits, mein Name ist Xiao Ming, ich bin 20 Jahre alt, aus China, ich spiele gerne Basketball
Das obige Beispiel entspricht:
<Script> Funktion Einführung (Country, Hobby) {return "Hallo allerseits, mein Name ist"+this.name+", dieses Jahr"+this.age+"Jahr, aus"+Country+", wie"+Hobby; } var xiaoming = {name: "xiaoming", Alter: 20} console.log (infize.apply (Xiaoming, ["China", "Play"])); // oder die console.log (intice.call (Xiaoming, "China", "Play"); </script>Es ist zu beachten, dass im strengen Modus von ECMascript 5 das erste wirkliche Argument von Call () und anwenden () zu diesem Wert wird, selbst wenn das in reale Argument bestehende Verfahren der ursprüngliche Wert oder sogar Null oder Undefined ist. Im ECMascript 3- und Nicht-Streng-Modus wird der übergebene Null und Undefined durch die globale Konfrontation ersetzt, während andere ursprüngliche Werte durch das entsprechende Wrapper-Objekt ersetzt werden.
Referenzen
[1], Autoritative JavaScript -Handbuch, 6. Ausgabe, Seite 189
[2], function.prototype.call (thisArg [, arg1 [, arg2,…]])
[3], function.prototype.apply (thisArg, argArray)