JS面试题之手写一个call方法

说明

首先,call方法是JS function中内置的一个方法,主要的作用有两个:

  • 改变函数的this指向
  • 向函数中传递参数

使用方式如下:

fn.call(obj, 100, 200)

接下来通过封装来实现一下call方法。

实现

首先,为了让每个函数的身上都能使用call方法,可以把call方法绑定到Function的原型上。

Function.prototype.myCall = function() {}

这样,就可以在每个函数的身上都能使用到myCall方法。

例如:

demoFn.myCall()

在myCall方法中,默认的this指向未来的实例化对象,也就是myCall方法的调用者(这里指的是要改变this指向的普通函数)。

为了一会方便调用,这里先把this进行存储。

Function.prototype.myCall = function() {
	var that = this
}

因为call方法允许传递最少两个,最多n个参数,第一个参数表示this的新指向,后续的参数表示的是传递到函数内部的参数值,这里在myCall方法中为了可以符合call方法的使用方式,需要通过arguments对象来进行模拟。

 var that = this // 这里将this存储起来
 var obj = Array.from(arguments)[0] // obj存储的是改变之后的this新的指向
 var args = Array.from(arguments).slice(1) // args存储的是传递过来的参数

同时,call方法还有一个特性,就是调用之后会立刻执行函数,所以这里我们可以把前面存储到that变量中的实例对象函数临时赋值给传递过来的新的对象,然后在其身上调用,调用完成后删除即可。

obj.temp_f = that

var res = obj.temp_f(...args)
// 在得到返回值之后,将对象身上的这个临时方法删除掉
delete obj.temp_f
return res

不要忘了给函数传递参数以及将返回值返回。

完整代码:

// 1. 首先,call方法属于Function构造函数原型上的方法
// 2. 需要传递最少两个参数,第一个参数是this指向,可能值是新的对象或者null ,第二个参数以及之后是传递的参数
Function.prototype.myCall = function() {
  // 此时在myCall内部,this指向调用者fn
  var that = this // 这里将this存储起来
  var obj = Array.from(arguments)[0] // obj存储的是改变之后的this新的指向
  var args = Array.from(arguments).slice(1) // args存储的是传递过来的参数
  // 接下来把之前的需要改变this指向的函数存储到新的this对象上,并且把参数传递进去
  obj.temp_f = that

  var res = obj.temp_f(...args)
  // 在得到返回值之后,将对象身上的这个临时方法删除掉
  delete obj.temp_f
  return res
}

// 测试代码
var obj = { user: 'zs' }

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

fn1.myCall(obj, 100, 200)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值