自定义javascript中call、bind、apply方法

2021-10-31  本文已影响0人  一颗冰淇淋

call、bind、apply都是Function原型上的方法,用于改变this的指向

自定义函数

js中的call、bind、apply是用c++代码实现的,我们这里使用js代码做一个模式,没有把所有的边界情况考虑进来,仅做一个简单的实现,三个函数在使用的时候有一些需要注意的地方,在定义的时候需要把这些情况考虑进去

call的实现

定义call函数需要注意

实现代码如下

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)

执行结果为

绑定的this为:{name: 'alice', fn: f}
传递的参数为:[1, 2, 3]

apply的实现

定义apply函数需注意

实现代码如下

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)

执行结果如下

绑定的this为:{'hello js', fn: f}
传递的参数为:['a', 'b', 'c']

bind的实现

定义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)

执行结果如下

绑定的this为:{0, fn: f}
传递的参数为:[20, 40, 30, 50]

以上就是call、bind、apply的实现方法,代码量不多,但是需要对this的指向比较了解,关于this指向也可以看看我其他的博文~

上一篇 下一篇

猜你喜欢

热点阅读