Las funciones de llamada y aplicación rara vez se usan en algunas operaciones simples de JavaScript. En otras grandes operaciones, como el desarrollo de aplicaciones web, estas dos funciones se pueden encontrar con frecuencia en el desarrollo del marco JS. También hay mucha información sobre las explicaciones de estas dos funciones, pero creo que mucha información está escrita o muy similar, y carece de explicaciones realistas. A continuación, trato de analizar y explicar estas dos funciones con una idea más clara y simple.
La copia del código es la siguiente:
Podemos considerar la llamada () y aplicar () como métodos de cierto objeto, e indirectamente las funciones de llamadas llamando a la implementación del método. El primer argumento de llamada () y aplicar () es el objeto principal que llama a la función. Es el contexto de llamada, y una referencia a él se obtiene a través de esto en el cuerpo de la función. Para llamar a la función f () en el método de objeto o, puede usar call () y aplicar () así: f.call (o) f.apply (o). [1]
Analicemos primero la llamada. Aquí está la explicación de la función de llamada por EcMascript 3rd Edition [2]: cuando el método de llamada se llama por un objeto de función (FUnc.call (0)), un parámetro necesario y varios parámetros no esenciales deben pasar. Su proceso de ejecución es el siguiente:
A, si el objeto que llama a la llamada no se está ejecutando, se lanza un error de typeError.
b, configure la lista de parámetros en vacío
c, si el método llamado pasa más de un parámetro, luego inserte arg1, arg2 ... en la lista de parámetros a su vez
D, devuelve el resultado de llamar a la llamada, reemplace esto en la función de llamada (func) con el parámetro 1 aprobado y trate la lista de parámetros aprobados como el parámetro de esta función.
De hecho, la función de llamada es el prototipo del objeto de función. Es decir, la función que las llamadas también deben ser una función. Al llamar a esta llamada, simplemente reemplace esto en la función que llame a la llamada con el objeto aprobado. Aquí hay un ejemplo:
<script> function c1 () {this.name = 'zhang san'; this.age = '24 '; this.sayName = function () {console.log ("Aquí está la clase C1, mi nombre es:"+this.name+"Mi edad es"+this.age); }} function c2 () {this.name = 'li si'; this.age = '25 '; } var c1 = new C1 (); var c2 = new C2 (); c1.sayName (); c1.sayname.call (c2); </script>Resultados de la ejecución:
Aquí está la categoría C1, mi nombre es: Zhang San My Age tiene 24 años
Aquí está la categoría C1, mi nombre es: li si mi edad es de 25
En el código anterior, se declaran dos clases, C1 y C2. C1 tiene dos propiedades, un método, y C2 también tiene dos propiedades igual que C1. Después de la instancia, c1.sayname () imprime las propiedades reales, pero C1.sayname.call (C2) imprime las propiedades de C2, ¿por qué es esto? Debido a que SayName () es una función y hay esto en el cuerpo de la función, cuando se ejecuta la llamada, esto será reemplazado por C2, por lo que el atributo de C2 eventualmente se imprimirá.
La diferencia entre aplicar y llamar radica en el paso de parámetros opcionales. Todos los parámetros opcionales de APLIC se almacenan en una matriz, ya que se ingresa un parámetro, mientras que la llamada se pasa a múltiples parámetros.
Entonces, ¿cuáles son las aplicaciones de las funciones de aplicaciones y llamadas? El primero es encontrar el elemento más grande en la matriz numérica en la red. Puede usar Math.max.apply (NULL, Array) directamente. El otro es usar aplicar y llamar para heredar, de la siguiente manera:
<script> function human (nombre, sexo) {this.name = name; this.sex = sexo; this.walk = function () {console.log ('estoy caminando'); }} function child () {human.call (this, "xiao ming", "masculino") this.paly = function () {console.log ('me gusta jugar mucho'); } this.intruduce = function () {console.log ('Hola a todos, yo'+this.name); }} var jinp = nuevo humano ('jack', 'masculino'); var xiaoping = new Child (); xiaoping.walk (); xiaoping.paly (); xiaoping.intruduce (); </script>Resultados de la ejecución:
Estoy caminando
Me gusta mucho jugar
Hola a todos, soy Xiao Ming
La función similar a llamar () y aplicar () es bind (), que es un nuevo método agregado en EcMascript 5, pero se puede simular fácilmente en EcMascript 3. La función de enlace también es el método functotype functoty en JavaScript. El contenido principal de este método es unir la función a un objeto. Cuando el método bind () está unido a la función f () y un objeto O se pasa como un parámetro, este método devolverá una nueva función y se llamará como un método de o. Cualquier argumento pasado a la nueva función se pasará a la función original. como sigue:
<script> Función Introducción (país, hobby) {return "Hola a todos, mi nombre es"+this.name+", este año"+this.age+"año, de"+country+", me gusta"+hobby; } var xiaoming = {nombre: "xiao ming", edad: 20} var jieshao = introducir.bind (xiaoming); console.log (Jieshao ("China", "Playing Ball")); </script>Resultados de la ejecución:
Hola a todos, mi nombre es Xiao Ming, tengo 20 años, de China, me gusta jugar baloncesto
El ejemplo anterior es equivalente a:
<script> Función Introducción (país, hobby) {return "Hola a todos, mi nombre es"+this.name+", este año"+this.age+"año, de"+country+", me gusta"+hobby; } var xiaoming = {nombre: "xiaoming", edad: 20} console.log (introducir.apply (xiaoming, ["china", "jugar"])); // o el console.log (introducir.call (Xiaoming, "China", "Play")); </script>Cabe señalar que en el modo estricto de Ecmascript 5, el primer argumento real de call () y aplicar () se convertirá en este valor, incluso si el argumento real es el valor original o incluso nulo o indefinido. En el modo ECMAScript 3 y el no riguroso, el NULL y indefinido aprobado serán reemplazados por la confrontación global, mientras que otros valores originales serán reemplazados por el objeto de envoltorio correspondiente.
Referencias
[1], Guía autorizada de JavaScript, sexta edición, página 189
[2], function.prototype.call (thathumarg [, arg1 [, arg2, ...]])
[3], function.prototype.apply (thantarg, argarray)