手書きの呼び出し、適用、バインド

(1)電話

通話の基本的な使い方

function person () {
  console.log(this.name)
}

let me = {
  name: 'zfb'
}

person.call(me) // zfb

person.call(me)は、person関数を呼び出し、person関数でこれをmeオブジェクトにポイントすることを意味します。callのパラメーターは1つずつ渡されます。

function person (a, b) {
  console.log(this.name)
  console.log(a)
  console.log(b)
}

let me = {
  name: 'zfb'
}

person.call(me, 1, 2)
// zfb
// 1
// 2

呼び出しの機能は、このポイントを変更することです。上記のこれは、meオブジェクトを指します。

(2)適用

適用と呼び出しの違いはです。適用するパラメータは配列です。パラメータであっても、配列に入れる必要があります。

受け取るとき、一つずつ

function person (a, b) {
  console.log(this.name)
  console.log(a)
  console.log(b)
}

let me = {
  name: 'zfb'
}

person.apply(me, [1, 2])
// zfb
// 1
// 2

(3)特別な事情

呼び出しと適用に渡される最初のパラメーターが未定義またはnullの場合、これはウィンドウを指します

function person (a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}

let me = {
  name: 'zfb'
}

person.apply(undefined, [1, 2])
person.call(undefined, 1, 2)
person.apply(null, [1, 2])
person.call(null, 1, 2)

出力:

(4)バインド

バインドの役割はこの点を変更することですが、呼び出しと適用とは異なり、呼び出しと適用はバインドの直後に実行されますが、バインドはすぐには実行されないため、再度呼び出す必要があります

function person (a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}

let me = {
  name: 'zfb'
}

person.bind(me, 1, 2) // 这时候控制台什么都没发生
person.bind(me, 1 ,2)() // 手动调用
// {name: "zfb"}
// 1
// 4 

つまり、bindは新しい関数を返し、新しい関数を呼び出す必要があります

const newFunction = person.bind(me, 1, 2) // 这时候控制台什么都没发生
console.log(newFunction) 
// ƒ person (a, b) {
//   console.log(this)
//   console.log(a)
//   console.log(b)
// }
newFunction() // 调用新返回的函数
// {name: "zfb"}
// 1
// 4

したがって、パラメーターを渡すと、パラメーターを新しい戻り関数に渡すことができます

person.bind(me)(1, 2)
// {name: "zfb"}
// 1
// 4 

nullまたは未定義のバインディングの場合、これもウィンドウを指します

person.bind(null)(1, 2)
person.bind(undefined)(1, 2)

(5)手書き呼び出し方式 

fn.call(obj)の本質はobj.fn()です

let me = {
  name: 'zfb',
  person: function (a, b) {
    console.log(this)
    console.log(a)
    console.log(b)
  }
}
me.person(1, 2)

したがって、私たちがしなければならないことは、これが指すオブジェクトにバインドされた関数をマウントすることです

Function.prototype.call = function (obj, ...args) {
  // 如果第一个参数是 null 或者 undefined 赋值为 window
  if (obj === null || obj === undefined) {
    obj = window
  }
  // 谁调用call,this就指向谁
  obj.p = this
  // 给obj添加一个方法,把参数传进去调用 如果有返回值就返回赋值给result
  var result = obj.p(...args)
  // 添加了之后要删除
  delete obj.p
  // 返回 result 这个返回值
  return result
}

同様に、適用は同じです

Function.prototype.apply = function (obj, args) {
  // 如果第一个参数是 null 或者 undefined 赋值为 window
  if (obj === null || obj === undefined) {
    obj = window
  }
  // 谁调用call,this就指向谁
  obj.p = this
  // 给obj添加一个方法,把参数传进去调用 如果有返回值就返回赋值给result
  var result = obj.p(...args)
  // 添加了之后要删除
  delete obj.p
  // 返回 result 这个返回值
  return result
}

callとapplyの唯一の違いは、受け入れられたパラメータータイプが使用されないことです。一方は分解後の値であり、もう一方は分解されていない配列です。

(6)バインド

bindは新しい関数を返します

Function.prototype.bind = function (obj, ...args) { // bind 函数传参数
  // bind 返回一个新函数
  return (...arg2s) => { // 新函数传参数
    return this.call(obj, ...args, ...arg2s) // call 返回一个返回值,将返回值返回
  }
}

バインドでパラメータを渡すには2つの方法があります

person.bind(me, 1, 2)() // bind 函数传参数
person.bind(me)(1, 2) // bind 返回的新函数传参数

以上がすべての知識ポイントです〜

おすすめ

転載: blog.csdn.net/Luckyzhoufangbing/article/details/108905177