关于实现call-apply-bind

关于实现call-apply-bind

call-apply-bind可以说是js里经常问到的问题了,如何自己实现一个call/apply/bind方法呢?这里做个记录
1、call
1、首先要每个函数都能调用,就应该给所有函数添加一个myCall方法

Function.prototype.myCall= function() {
}

2、在myCall中要可以去执行调用的函数
例如:

function foo() {
  console.log("foo函数被执行", this)
}
foo.myCall(xxx)

在这里,foo函数调用了myCall方法,因此在myCall里应该要拿到foo函数,并且调用。因此在myCall里添加获取foo的代码

Function.prototype.myCall= function() {
	// 问题: 得可以获取到是哪一个函数执行了myCall
	//获取要执行的函数
	var fn = this
	fn()
}

3.传入参数,如果传入的thisArg不是个对象,那么就需要进行处理。

Function.prototype.myCall= function(thisArg,...args) {
	// 问题: 得可以获取到是哪一个函数执行了myCall
	//获取要执行的函数
	var fn = this
	// 2.对thisArg转成对象类型(防止它传入的是非对象类型)
 	thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window
	fn()
}

4、调用函数,并将结果传出去

Function.prototype.myCall= function(thisArg,...args) {
	// 问题: 得可以获取到是哪一个函数执行了myCall
	//获取要执行的函数
	var fn = this
	// 2.对thisArg转成对象类型(防止它传入的是非对象类型)
 	thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window
	// 3.调用需要被执行的函数
  	thisArg.fn = fn
  	var result = thisArg.fn(...args)
  	delete thisArg.fn
  	// 4.将最终的结果返回出去
  	return result
}

注意:在执行thisArg.fn = fn之后,会给thisArg加上fn,因此在调用完获取结果之后,需要将此增加的删除。
2、apply函数
与call函数实现是类似的思路,不一样的是传入参数的格式不一样,因此对参数格式进行限定就行。实现如下:

// 自己实现myApply
Function.prototype.myApply= function(thisArg, argArray) {
  // 1.获取到要执行的函数
  var fn = this

  // 2.处理绑定的thisArg
  thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window

  // 3.执行函数
  thisArg.fn = fn
  var result
  //处理传参
  argArray = argArray || []
  result = thisArg.fn(...argArray)

  delete thisArg.fn

  // 4.返回结果
  return result
}

3、binb函数
bind函数与call、apply函数的区别是,call/apply返回的是执行后的结果,而bind返回的是替换后的函数。实现思路类似call,区别在于:1、返回函数 2、对参数需要进行合并,实现如下:

Function.prototype.myBind = function(thisArg, ...argArray) {
  // 1.获取到真实需要调用的函数
  var fn = this

  // 2.绑定this
  thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window

  function proxyFn(...args) {
    // 3.将函数放到thisArg中进行调用
    thisArg.fn = fn
    // 特殊: 对两个传入的参数进行合并
    var finalArgs = [...argArray, ...args]
    var result = thisArg.fn(...finalArgs)
    delete thisArg.fn

    // 4.返回结果
    return result
  }

  return proxyFn
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值