模拟实现call、 apply 、bind 函数

本文主要用来理解底层函数的原理, 并没有苛求一定用最原始的语法解决问题。 好的 ,我们开始
1.call函数
首先,我们要知道 call  的用法 ,可以这里
call 主要做了四件事 :
1).创建一个变量指向call函数的第一个参数,如果为null 或undefinedi则指向window, 如果是其他基本变量,则调用对应的构造函数返回对应的对象;如下代码简化。
2).把调用call的函数置为对象的方法。
3).调用函数 传入对应的参数。
4).obj 指向的是传入的对象,避免污染,删除添加fn方法.

Function.prototype.myCall=function(){
    let obj=arguments[0]||window;  // 获取想要指向的对象 一个参数为null 时候 指向window;
    obj.fn = this;
    const params= [...arguments].slice(1); // 获取通过call传入的参数  ,如果是apply 可以改成 params = arguments[1];
    obj.fn(...params);
    delete obj.fn ; // 删除添加的 方法。
}
var a= {b:2};
function test(context){
 console.log(this.b)
 console.log('context:',context);
}

test.myCall(a,222); // 2   context:222

2.apply 函数的原理类似,传参只接收两个有效参数,且第二个参数形式是数组 。
3.bind 函数为目标函数绑定好this ,并没有立即执行,而是返回一个 绑定好的函数, 供在其他地方调用。先看下bind函数的特点
1) bind函数支持传参,并且返回的新函数也同样支持传参,两者是拼接到一起 传给目标函数。
2) 绑定this 的过程中, 返回的函数如果 作为构造函数,new 操作符的优先级更高,即new 出的实例对象绑定this ,  但是传入得参数还是有效的 。 ok   下面实现内容 
 

Function.prototype.myBind = function (context){
   if(typeof this!=='function'){
      throw new Error(`Function.prototype.bind - what is trying to be bound is not callable`);  // 如果调用bind 的 是非函数 throw error
    }
     const self = this;
     const args= [...arguments].slice(1); // binding 时传入的参数。
     const bindedFun= function (){
           const bindedArg =Array.prototype.slice.call(arguments,0); // 真实调用时候 传入的参数 转化整数组对象。
           const params = [...args,...bindedArg ]; // 合并参数
            self.call(this instanceof bindedFun ?this:context,...params);
         }
     return bindedFun;
}

function test (name,age){
   console.log(this.value);
console.log('name',name);
console.log('age',age);
}


var obj={value:6};

var test1 = test.myBind(obj,'xuezh');

test1(29);

 self.call(this instanceof bindedFun ?this:context,...params);  // 这一步比较重要 判断 this  是否在bindedFun 原型链上,    返回的函数作为构造函数,在new 后生成的实例对象的 在构造函数的原型链上。具体可以查看这篇文章 new 都做了什么
继承的知识


 

发布了16 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42317878/article/details/104833353
今日推荐