乐趣区

关于javascript:自定义javascript中callbindapply方法

call、bind、apply 都是 Function 原型上的办法,用于扭转 this 的指向

自定义函数

js 中的 call、bind、apply 是用 c ++ 代码实现的,咱们这里应用 js 代码做一个模式,没有把所有的边界状况思考进来,仅做一个简略的实现,三个函数在应用的时候有一些须要留神的中央,在定义的时候须要把这些状况思考进去

  • 当传入的值是根本数据类型时,call、apply、bind 办法会将它转变成援用数据类型,如传入的字符串变成了 String 类型,通过 Object() 能够做这一转换
  • 当没有传递须要扭转的 this 指向时,函数的 this 指向 window(非严格模式下)
  • 当传递的 this 指向为 null、undefined 时,函数的 this 指向 window(非严格模式下)

call 的实现

定义 call 函数须要留神

  • 第一个参数接管扭转后的 this 指向,从第二个参数开始接管函数执行所须要的参数

实现代码如下

Function.prototype.iCall = function (thisArg, ...args) {
  // 1. 获取执行函数
  var fn = this
  
  // 2. 将函数绑定到传递的对象上
  thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
  thisArg.fn = fn
  var result = thisArg.fn(...args)
  
  // 3. 删除传递对象的 fn 函数
  delete thisArg.fn
  
  // 4. 返回后果
  return result
}

function foo(...args) {console.log('绑定的 this 为:', this)
  console.log('传递的参数为:', args)
}

var user = {name: 'alice'}

// 将 foo 函数 this 指向改为 user,并传递参数 1,2,3
foo.iCall(user, 1, 2, 3)

执行后果为

apply 的实现

定义 apply 函数需注意

  • 第一个参数接管扭转后的 this 指向,第二个参数接管函数执行所须要的参数组成的【数组】

实现代码如下

Function.prototype.iApply = function(thisArg, args){
   // 1. 获取执行函数
   var fn = this
   // 2. 将函数绑定到传递的对象上
   thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
   thisArg.fn = fn
   var result = thisArg.fn(...args)
 
   // 3. 删除传递对象的 fn 函数
   delete thisArg.fn
 
   // 4. 返回后果
   return result
}

function foo(...args){console.log('绑定的 this 为:', this)
  console.log('传递的参数为:', args)
}

var str = "hello js"
var arr = ['a', 'b', 'c']

foo.iApply(str, arr)

执行后果如下

bind 的实现

定义 bind 函数需注意

  • 第一个参数接管扭转后的 this 指向,第二个参数接管函数执行所须要的参数
  • bind 函数不会立刻调用函数,而是返回一个新的函数,新函数依然能够持续传递参数
Function.prototype.iBind = function (thisArg, ...args) {
  // 1. 获取执行函数
  var fn = this
  
  // 2. 将函数绑定到传递的对象上
  thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
  thisArg.fn = fn
  
  return function (...params) {
    // 3. 获取函数执行的后果
    var result = thisArg.fn(...args, ...params)
    
    // 4. 删除传递对象的 fn 函数
    delete thisArg.fn
    
    // 5. 返回后果
    return result
  }
}

function foo(...args) {console.log('绑定的 this 为:', this)
  console.log('传递的参数为:', args)
}
var num = 0

var fn = foo.iBind(num, 20, 40)
fn(30, 50)

执行后果如下

以上就是 call、bind、apply 的实现办法,代码量不多,然而须要对 this 的指向比拟理解,对于 this 指向也能够看看我其余的博文~

退出移动版