面试题 - 实现一个 call/apply 方法

面试题 - 实现一个 call/apply 方法

题目

实现一个 call / apply 方法。

解析

call 和 apply 方法一个重要的特征就是第一个参数可以绑定 this 指向。如下案例:

var a = 100;
var obj = {
  a:1000;
}
function fun(){
  console.log(this.a);//1000
}
fun.call(obj);

如上所示,如果没有使用 call 方法显式地将 obj 对象绑定到 this。fun 函数中 this 指向的就是 window。而 apply 与 call 的区别就是 apply 方法从第二参数开始是以数组的形式传参。

实现 call/apply 方法有两个关键点:

  1. 绑定 this。this 指向问题可以用一句话概括,“谁调用,this 就指向谁”。所以绑定 this 就需要将调用的方法添加到传过来的对象上去。再通过对象去调用。这样就可以实现将 this 指向这个对象。
    即结合以上案例可以简单地理解为是将 fun 方法添加到 obj 对象的属性上。然后通过 obj 对象的属性去调用 fun 方法,就可以实现 fun 中的 this 指向 obj。

  2. 传递参数。除了将方法添加到对象上,还需要将参数进行传递。传递参数可以有三种方式, apply,eval(循坏数组,拼接字符串),ES6 的数组解构。以下案例中使用的是 ES6 的数组解构。

代码

实现一个 call 方法

Function.prototype._call = function(){
	  //1.将第一个参数(绑定this的对象)和剩余参数解构出来
	  let [thisObj,...arg] = [...arguments];
	  //2.如果第一个参数为空,则this为全局对象
      if(!thisObj){
          thisObj = typeof window === 'undefined'? global:window;
      }
      //3.把this(调用_call的方法) 赋值到该对象的一个属性上
      thisObj._this = this;
      //4.调用对象绑定的方法。
      var result = thisObj._this(...arg);
      //5.删除绑定的属性
      delete thisObj._this;
      //6.返回调用结果
      return result;
    }
    
    //测试
    var num = 18;
    function Person(a,b) {       
        console.log(this.num + a + b);//60
    }
    var obj = {     
        num:20
    }
    Person._call(obj,20,20);

实现一个 apply 方法。

Function.prototype._apply = function(){
	  //1.将第一个参数(绑定this的对象)和数组参数(这里是apply与call的区别)解构出来
	  let [thisObj,arg] = [...arguments];
	  //2.如果第一个参数为空,则this为全局对象
      if(!thisObj){
          thisObj = typeof window === 'undefined'? global:window;
      }
      //3.把this(调用_apply的方法) 赋值到该对象的一个属性上
      thisObj._this = this;
      //4.调用对象绑定的方法。
      var result;
      if(arg){
	      if(!Array.isArray(arg)){
	         throw new Error("参数为数组")
	      }else{
	         result = thisObj._this(...arg);
	      }
      }else {
          result = thisObj._this();
      }
      //5.删除绑定的属性
      delete thisObj._this;
      //6.返回调用结果
      return result;
    }
   
    //测试
    var num = 18;
    function Person(a,b) {       
        console.log(this.num + a + b);//60
    }
    var obj = {     
        num:20
    }
    Person._apply(obj,[20,20]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值