[面试题] 手写call、apply、bind

call

 const obj1 = {
     name:'张三',
     age:18,
     sex:'男',
     // 存储在对象obj1 中的函数 this指向默认是 对象obj1
     // this.name , this.age , this.sex 调用的应该是 obj1 中的数据
     fun:function(addr,phone){
         console.log( this.name );
         console.log( this.age );
         console.log( this.sex );
         console.log( addr );
         console.log( phone );
     }
 }

 obj1.fun('北京' , 12341);

在这里插入图片描述

 const obj1 = {
     name:'张三',
     age:18,
     sex:'男',
     // 存储在对象obj1 中的函数 this指向默认是 对象obj1
     // this.name , this.age , this.sex 调用的应该是 obj1 中的数据
     fun:function(addr,phone){
         console.log( this.name );
         console.log( this.age );
         console.log( this.sex );
         console.log( addr );
         console.log( phone );
     }
 }

  const obj2 = {
      name:'李四',
      age:20,
      sex:'女',
  };

  obj1.fun.call(obj2 , '天津' , 12345);

在这里插入图片描述
我们可以这样理解:把fun方法放到obj2 里面,然后我在obj2 的环境下执行fun(如果obj2 没有值,那就相当再window环境下执行fun,this是指向window的),相当obj2.fun( ‘天津’ , 12345)或者fun( ‘天津’ , 12345),然后我再obj2里面删除fun方法。知道原理了,那么我们按照上面的例子来自己封装下call方法:

手写call

// obj1.fun.newCall(obj2 , '天津' , 12345);

Function.prototype.newCall = function (context,...arg) {
	// 当call的第一个参数没有或者是null的时候,this的指向是window
    let ctx = context || window;
    
    //this是谁?谁调用这个call,this就指向谁,所以this指向obj1.fun
    //把obj1.fun 放到ctx里面,就是赋值给 ctx.fn,那么ctx.fn就与obj1.fun等价了
    ctx.fn = this;
    
   
    //用指定的上下文去执行当前调用newCall的函数
    const res = ctx.fn(...arg);
    //删除 避免污染全局
    delete ctx.fn;
    // 因为函数可能有返回值,所以把结果也返回出去给他们
    return res
};

在这里插入图片描述
在这里插入图片描述

apply


 const obj1 = {
     name:'张三',
     age:18,
     sex:'男',
     // 存储在对象obj1 中的函数 this指向默认是 对象obj1
     // this.name , this.age , this.sex 调用的应该是 obj1 中的数据
     fun:function(addr,phone){
         console.log( this.name );
         console.log( this.age );
         console.log( this.sex );
         console.log( addr );
         console.log( phone );
     }
 }

  const obj2 = {
      name:'李四',
      age:20,
      sex:'女',
  };

  obj1.fun.apply(obj2 , [ '天津' , 12345 ])

在这里插入图片描述

手写apply

 Function.prototype.newApply = function (context, arg) {
     // 当call的第一个参数没有或者是null的时候,this的指向是window
     let ctx = context || window;

     //this是谁?谁调用这个call,this就指向谁,所以this指向obj1.fun
     //把obj1.fun 放到ctx里面,就是赋值给 ctx.fn,那么ctx.fn就与obj1.fun等价了
     ctx.fn = this;
     
     //用指定的上下文去执行当前调用newCall的函数
     const res = ctx.fn(...arg);
     //删除 避免污染全局
     delete ctx.fn;
     // 因为函数可能有返回值,所以把结果也返回出去给他们
     return res
 };

在这里插入图片描述
在这里插入图片描述

bind

 const obj1 = {
     name:'张三',
     age:18,
     sex:'男',
     // 存储在对象obj1 中的函数 this指向默认是 对象obj1
     // this.name , this.age , this.sex 调用的应该是 obj1 中的数据
     fun:function(addr,phone){
         console.log( this.name );
         console.log( this.age );
         console.log( this.sex );
         console.log( addr );
         console.log( phone );
     }
 }

  const obj2 = {
      name:'李四',
      age:20,
      sex:'女',
  };

  obj1.fun.bind(obj2 , '天津' , 12345)();

在这里插入图片描述

手写bind

在这里插入图片描述

在这里插入图片描述
bind还支持另一种传参方法,所以需要修改下

 obj1.fun.bind(obj2)( '天津', 12345);

在这里插入图片描述

 Function.prototype.newBind = function (context, ...arg) {
     // 当call的第一个参数没有或者是null的时候,this的指向是window
     let ctx = context || window;

     //this是谁?谁调用这个call,this就指向谁,所以this指向obj1.fun
     //把obj1.fun 放到ctx里面,就是赋值给 ctx.fn,那么ctx.fn就与obj1.fun等价了
     ctx.fn = this;
     
     return (...argAgu)=>{
         ctx.fn(...arg,...argAgu)
     }
 };

…arg

在这里插入图片描述



参考:
哔哩哔哩—JS中this指向以及手写call、apply、bind

es6解构赋值+剩余参数+扩展运算符

[ES6] this指向 window 事件源 箭头函数的this指向 改变this指向 call apply bind

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值