面试题 - 实现一个 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]);
发布了280 篇原创文章 · 获赞 2497 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/104691566
今日推荐