Funciones de uso e implementación manuscrita de llamar, aplicar y vincular

uso

1.aplicar

applyAcepta dos parámetros, el primer parámetro es thisel puntero y el segundo parámetro es el parámetro aceptado por la función, pasado en forma de matriz.

La función original se ejecutará inmediatamente después de cambiar thisel puntero, y este método solo cambia temporalmente thisel puntero una vez.

gramática:

func.apply(thisArg, [argsArray])

thisArg: el objeto señalado por this cuando la función se está ejecutando, requerido
argsArray: los parámetros pasados ​​cuando la función se está ejecutando, en forma de matriz, opcional

ejemplo:

function fn (a,b,c) {
    console.log(this.name)
    console.log(a, b, c)
}
let obj = {name: '科比'}
fn.apply(obj, [1,2,3])
// 输出  科比 1 2 3

2.llamar

Del applymismo modo, thisla función original se ejecutará inmediatamente después de cambiar el puntero, y este método solo cambia temporalmente thisel puntero una vez.

La diferencia es que los parámetros pasados ​​en apply deben estar en forma de matriz, mientras que call no tiene esta restricción.

gramática:

func.call(thisArg[, args1, args2, args3,....])

thisArg: el objeto al que apunta this cuando la función se está ejecutando, se requiere
args1, etc.: parámetros pasados ​​cuando la función se está ejecutando, opcional

ejemplo:

function fn (a,b,c) {
    console.log(this.name)
    console.log(a, b, c)
}
let obj = {name: '科比'}
fn.call(obj, 1, 2, 3)
// 输出  科比  1 2 3

3.enlazar

El método de vinculación es muy similar a la llamada: el primer parámetro también thisapunta a y lo que se pasa más adelante también es una lista de parámetros (pero esta lista de parámetros se puede pasar varias veces).

Después de cambiar thisel puntero, no se ejecutará inmediatamente, pero devolverá una thisfunción que cambia el puntero de forma permanente.

gramática:

func.bind(thisArg[, args1, args2, args3,....])
function fn (a, b, c, d) {
    console.log(this.name)
    console.log(a, b, c, d)
}
let obj = {name: '科比'}
let bindFn = fn.bind(obj, 1, 2, 3)
bindFn('bind') // 输出  科比  1 2 3 'bind'

Como se puede ver en el ejemplo , se devuelve una nueva función, se señala  bindal ejecutar la nueva función y luego los parámetros pasados ​​se fusionan con los parámetros pasados ​​cuando se llama a la nueva función y se pasan juntos a la nueva función.thisobjbind

Implementación manuscrita:

Puede saber por lo anterior aplicar, llamar y vincular el uso:

Aplicar, llamar y vincular todos los puntos a aplicar, lo que puede cambiar esto
. La llamada ejecutará la función llamada y la vinculación devuelve una nueva función.
El segundo parámetro de apply requiere una matriz, mientras que call y bind no limitan el tipo de datos. Pasará los parámetros restantes a la función juntos. Bind también fusionará los parámetros pasados ​​cuando se llame a la nueva función y los pasará al nueva función.
Todos están vinculados al prototipo de función.
Veamos cómo implementarlo a mano. Porque todos están vinculados al prototipo de Función.

1.aplicar

Function.prototype.apply = function (context, args) {
  // 不传默认是全局,window
  context = context || window
  // args不传时默认是空数组,防止下面用spread操作符时报错
  args = args ? args : []
  // 把this存到context.fn,这里的this是调用的函数
  context.fn = this
  // 执行调用的函数,this指向context,参数用spread操作符扩展
  const res = context.fn(...args)
  // 删除,不污染context
  delete context.fn
  // 返回res
  return res
}
function fn (a,b,c) {
    console.log(this.name)
    console.log(a, b, c)
}
let obj = {name: '码上游'}
fn.apply(obj, [1,2,3])
// 输出  码上游  1 2 3

2.llamar

llamar es lo mismo que aplicar. La razón principal es que los parámetros son diferentes de aplicar. Solo haga pequeños cambios;

El código se muestra a continuación:

Function.prototype.call = function (context, ...args) {
  // 不传默认是全局,window
  context = context || window
  // args不传时默认是空数组,防止下面用spread操作符时报错
  args = args ? args : []
  // 把this存到context.fn,这里的this是调用的函数
  context.fn = this
  // 执行调用的函数,this指向context,参数用spread操作符扩展
  const res = context.fn(...args)
  // 删除,不污染context
  delete context.fn
  // 返回res
  return res
}

Se utiliza principalmente al callobtener el segundo parámetro de la función , de modo que todos los parámetros restantes se puedan obtener en argumentos y todo lo demás sea igual.argsspread操作符

function fn (a,b,c) {
    console.log(this.name)
    console.log(a, b, c)
}
let obj = {name: '科比'}
fn.call(obj, 1, 2, 3)
// 输出  科比  1 2 3

3.enlazar

Bind es diferente. Devuelve una nueva función. Esta nueva función se puede llamar o utilizar como constructor mediante newoperadores, por lo que es necesario hacer una distinción aquí.

Function.prototype.bind = function (context, ...args) {
  // 不传默认是全局,window
  context = context || window
  // 把this存到fn,这里的this是调用的函数
  let fn = this
  return function newFn (...fnArgs) {
    let res
    // 要考虑新函数是不是会当作构造函数
    if (this instanceof newFn) {
      // 如果是构造函数则调用new 并且合并参数args,fnArgs
      res = new fn(...args, ...fnArgs)
    } else {
      // 当作普通函数调用 也可以用上面定义的_call
      res = fn.call(context, ...args, ...fnArgs)
    }
    return res
  }
}

verificar

function fn (a, b, c, d) {
    console.log(this.name)
    console.log(a, b, c, d)
}
let obj = {name: '科比'}
let bindFn = fn.bind(obj, 1, 2, 3)
bindFn('bind') // 输出  科比  1 2 3 'bind'
 
let bindFn = fn.bind(obj, 1, 2, 3)
let instance = new bindFn()
instance.constructor === fn // true

Supongo que te gusta

Origin blog.csdn.net/LoveHaixin/article/details/133038002
Recomendado
Clasificación