模拟实现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 (...rest){
           
           const params = [...args,...rest ]; // 合并参数
            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 都做了什么
继承的知识

 

注意:

1、bind操作只有第一次绑定有效果,之后再次进行绑定,不会有效果

2、new操作的绑定操作优先度要高于bind,事实上,也会高于apply和call

一旦函数通过bind绑定了有效的this对象,那么在函数执行过程中this会指向该对象,即使使用call、apply也不能改变this的指向;



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值