aplicar enlace de llamada relacionado
Para aplicar enlace de llamada, también escribí un artículo de nivel de entrada muy detallado antes de aplicar, llamar, enlazar el uso y las diferencias
Después de comprender el uso, es mejor comprender su principio de implementación para que pueda comprenderlo a fondo
La diferencia entre los tres
call
Yapply
están hechos para abordarthis
puntos cambiantes . El efecto es el mismo, pero la forma de pasar los parámetros es diferente- Además del primer parámetro,
call
puede recibir una lista de parámetros yapply
solo aceptar una matriz de parámetros bind
El efecto es el mismo que los otros dos métodos, excepto que el método devuelve una función. No se ejecutará de inmediato
Llamada escrita a mano
-
Manejar las necesidades:
- Cambie este punto. Apuntar a la ventana por defecto
- Puede recibir múltiples parámetros
- Ejecute el método después de cambiar esta solicitud
- Todos los métodos montan esto
myCall
-
Analizar las ideas de realización:
- Para
this
. Solo recuerde, quien llame a este método, esto apuntará a (excepto para las funciones de flecha), y dejará que el objeto / ventana pase para llamar al método. - Reciba múltiples parámetros:
arguments
o nueva sintaxis es6:...args
- Ejecute la función inmediatamente, rocíe agua
- Se montan todos los métodos, luego se usa la cadena del prototipo, se monta en el
Function
objeto
- Para
-
Todo está listo, comienza a lograr:
Function.prototype.myCall = function(context, ...args) {
// 默认的window对象
context = context && typeof context === 'object' ? context : window
// 防止覆盖掉原有属性
const key = Symbol()
// 这里的this为需要执行的方法
context[key] = this
// 方法执行
const result = context[key](...args)
delete context[key]
return result
}
- Resumir la implementación
- Primero, asegúrese de que el nuevo puntero sea un tipo de objeto
object
. De lo contrario, todas son ventanas por defecto. Por supuesto, typeof null también es igual a "object". Entonces tenemos que usar un juicio para asegurarnos de que el contexto existe Symbol
Rol: prevenir el conflicto de nombres de atributos. ¿Por qué quieres hacer esto? Debido a que necesitamos poner una propiedad en el nuevo objeto, esta propiedad es la antiguathis
. Pero, ¿cómo garantizar que las nuevas propiedades y nocontext
los atributos originales entren en conflicto? Entonces usaSymbol
- Podría estar por encima de toda
context[key] = this
duda. Es por eso que, al final, ¿por qué debería la nuevacontext
versión de este viejo objeto? Habrá principios de explicación del código más adelante - No hay problema con el método de ejecución ~
- Finalmente
delete
, nuestra nueva propiedad, después de todo, no puede afectar elcontext
objetivo original.
- Primero, asegúrese de que el nuevo puntero sea un tipo de objeto
¿Cuál es el contexto de expansión pequeña [clave] = esto?
La comprensión context[key] = this
tiene un significado muy importante para toda la implementación del código escrito a mano.
En primer lugar, el principio que se ha mantenido inalterado durante miles de años: quien llama a un método, este señala a quién.
Entonces, ¿por qué nocontext
llamar al método correspondiente?
Porquecontext
básicamente no existe un método correspondiente
Utilice un pequeño ejemplo para comprender el problema.
let data = {
key: 1,
name: 'Jioho',
say: function() {
console.log(this.name)
}
}
function fn() {
console.log(this.name)
}
data.say() // Jioho
fn() // 打印为空
// 那如果这样:
data.sayfn = fn
data.sayfn() // Jioho
- Gap apareció, siempre que el método correspondiente en el que un objeto, el método pueda obtener la
this
instancia actual context[key] = this
Lo mismo es verdad. Esta vezthis
es la función originalthis
. Esto en la función original tiene su propio método. Así que asignamos directamente todo esto acontext
. Al igual que la línea 16 del código anterior- Como comenzamos
key
por quéSymbol
. Es solo que tenemos miedo de tener el mismo nombre si no se llama a nuestro 16º nuevo atributosayfn
. Llamadosay
, nuestras operaciones posteriores afectarán las propiedades del objeto original ¡Este es un problema que no debe surgir!
Aplicar escritura a mano
Si la escritura a mano llama después de entender, aplique solo una pregunta, pase Senado
No es necesario cambiar el resto del código, solo debe ser un tipo de matriz al recibir el segundo parámetro
Function.prototype.myApply = function(context, args = []) {
// 默认的window对象
context = context && typeof context === 'object' ? context : window
// 防止覆盖掉原有属性
const key = Symbol()
// 这里的this为需要执行的方法
context[key] = this
// 方法执行
const result = context[key](...args)
delete context[key]
return result
}
Enlace de escritura a mano
-
Manejar las necesidades:
- Cambie este punto. Apuntar a la ventana por defecto
- Parámetros antes de llamar a bind, puede pasar múltiples
- En la función devuelta, puede continuar pasando parámetros. Esta escena sigue siendo muy práctica.
- Todos los métodos montan esto
myBind
-
Analizar las ideas de realización:
- No es necesario cambiar este punto para decir, si está escrito a mano, usar el original
apply
ocall
lo hará. - Puede pasar varios parámetros antes de llamar a bind, todavía se usa
arguments
o se...args
recibe unificado - bind necesita devolver uno
函数
. Y puede continuar pasando parámetros en la nueva función, luego debe usar cierres - Se montan todos los métodos, luego se usa la cadena del prototipo, se monta en el
Function
objeto
- No es necesario cambiar este punto para decir, si está escrito a mano, usar el original
Function.prototype.myBind = function(context, ...args) {
context = context && typeof context === 'object' ? context : window
const _self = this
return function(...args2) {
return _self.apply(context, [...args, ...args2])
}
}
// 接下来验证一下:
var data = {
baseCount: 10 }
function add(num1, num2) {
return this.baseCount + num1 + num2
}
// 调用方法
var addBind = add.myBind(data, 1)
addBind(2) // 13
// 或者这样写
add.myBind(data, 1)(2) // 13
- Resumir la implementación
- Los mismos años
context
para lograr - Debido a que hay formas de recibir una pluralidad de parámetros dos veces, solíamos
...args
recibir también debe haber una matriz de. Por lo tanto, es más apropiado usar aplicar en la función devuelta.
- Los mismos años
No subestimes la forma aparentemente extraña de escribir bind. ¿Por qué tienes que pasar el parámetro dos veces? Cuando hablemos de currying complejo más adelante, descubriremos el encanto de bind now.
La publicación original se publicó en: aplicar la nueva dirección de blog relacionada con la vinculación de llamadas , puede verificarla si está interesado