Ⅰ、call 函数的简介:

1、call 函数的用法:

fn.call(obj,1,2);

A、call() 函数中的第一个参数表示:想让 this 指向的对象 (obj);
B、call() 函数中的第二及以后参数表示:传进去的实参;

2、call 函数的功能:

其一、让函数立执行;
其二、可改变 this 的指向;
其三、可实现继承问题;

Ⅱ、call 函数如何调用:

1、call() 函数的调用过程:

var obj = { a: 1 };
    function fn(x, y) {  // 每个函数都会有 call 方法;
      console.log(this);
      return x + y;
    }

    console.log(fn.call(null, 1, 2)); 
    // 此时的输出结果为:Window, 3;
    // 若此时的 call() 函数中的第一个参数未传值,或传值为 null 时,此时的 fn 中的 this 指向为:Window; 
                                    
    console.log(fn.call(obj, 1, 2)); 
    // 此时的输出结果为:{a: 1}, 3;
    // 若此时的 call() 函数中的第一个参数非空而是 obj ,那么此时的 fn 中的 this 指向为:obj; 

2、call() 函数的调用结果展示为:

在这里插入图片描述

Ⅲ、模拟 call 函数的实现原理;

1、对 call 函数原理的模拟 (即:实现自己的 myCall 方法) ;


	Function.prototype.myCall = function (context) {  
	// 其中 context 参数是指:改变 this 指向,而待指向的的参数值(如:obj);
	// 此时是在 Function 的原型链上来添加 myCall() 函数, 那么此时该函数中的 this 指向的是:调用该 myCall() 方法的实例或函数;
	
      // 处理参数(即:实参); 
      var args = [...arguments].slice(1);  
      // 将 arguments 的值从第二个截取后,放到 args 的数组里;
      // 该操作是将传入的实参值转化成数组,以待后面使用;

      context = context || window;   
      // 当传的值为 null 或没传值时(均为:false),此时 context 的值为:Window;      
      // 当传值时(为:true),此时的 context 的值为:context;

     
      context.fn = this; 
       // 此时 this 指向的是:将来调用 myCall 方法的那个函数;
       // 而又由于 context 调用 fn 这个属性是指向 this, 因此此时的 this 就指向了 context;  那么此时就完成了 this 指向 context 的目的;
       // 该操作是:让将来调用 myCall 方法的那个函数,封装到 context 的一个属性中去(即:context.fn);
       // 那么此时的 context.fn 就代表的是调用 myCall 方法的那个函数,它是一个函数;

      var r = context.fn(...args); 
      // 该操作是:调用 context.fn() 函数,也就是调用了 '调用 myCall' 的函数;
      // 并传参为:'...args', 也就是将 args 数组中的值展开作为参数传入函数中;
      // 此时也就完成了,将 this 的指向为:context;     且还运行了 '调用 myCall' 的函数,并将参数传进去; (即:已经实现了 call() 函数的功能); 

      return r;
      // 然后再将操作后的值返回;
    }

    var obj = { a: 1 };
    function fn(x, y) {  
      console.log(this);
      return x + y;
    }


    var sum = fn.myCall(obj, 1, 2);
    console.log(sum); 
    // 此时的输出结果为:'{a: 1, fn: ƒ}', 3;   
    // 输出结果都正确,只是 context 中添加一个 fn 属性,但添加一个属性也是没大影响的;
    // 注意:此时并没有模拟 this 指向 Window 的情况;

2、模拟的 myCall() 函数的调用结果展示为:

在这里插入图片描述

Ⅳ、小结:

其一、哪里有不对或不合适的地方,还请大佬们多多指点和交流!

其二、如果关于 call 、apply、bind 用法和实现原理不详细,请参考如下地址文章:https://blog.csdn.net/weixin_43405300/article/details/121894586?spm=1001.2014.3001.5501

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐