手动实现call,apply,bind函数

实现call

Function.prototype.myCall = function (targetObj, ...resule) {

   // 判断传入对象的有无
  targetObj = targetObj || window;
 
   // 向传入对象上挂在this指向,此时this指向调用myCall函数
  targetObj.fn = this;
    

    // 在内部使用传入对象调用fn方法,这样可以实现更改this指向,指向为传入的目标对象
  let value = eval('targetObj.fn(...resule)');

   // 删除目标对象的fn方法
  delete targetObj.fn

   // 返回调用的结果
  return value;
}

let obj = {
    uname: 'Tom'
}

function demo(a, b){
    console.log(this.uname, a, b);
}

demo();// undefined undefined undefined

demo.myCall(obj, 1, 2);
// Tom 1 2

实现apply (主体和call差不多, 不同的传入参数的方式)

Function.prototype.myApply = function (targetObj, resule) {

  targetObj = targetObj || window;

  targetObj.fn = this;

  let value = eval('targetObj.fn(...resule)');

  delete targetObj.fn

  return value;
}

let obj = {
    uname: 'Tom'
}

function demo(x, y){
    console.log(this.uname, x, y);
}

demo();// undefined undefined undefined

demo.myApply(obj, [1, 2]);
// Tom 1 2

实现bind

Function.prototype.myBind = function (targetObj, ...resule) {
    
    // 判断调用的对象是否是一个函数
    if (typeof this !== "function") {
      throw new Error("this must be a function");
    }
    
    // 创建变量保存this指向
    // 此时this指向外部调用的函数
    let self = this;
    
    // 创建要返回的函数
    let backFunc = function () {
       // 先判断调用对象的this是否和本函数时同一个this
       // 是则更改this指向到自身,(实际上最后返回的也只是this指向自身的函数)
       // 不是则改变调用者this指向指向传入对象,将参数传递到调用的this中。
 			self.apply(this instanceof self ? 
            this : targetObj, resule.concat(Array.prototype.slice.call(arguments)));
    }
    
    // 判断调用是有原型
    if(this.prototype) {
     // 有则赋值原型到返回的函数上
      backFunc.prototype = Object.create(this.prototype);
    }
    // 返回函数
    return backFunc;
}

let obj = {
    uname: 'Tom'
}

function demo(x, y){
    console.log(this.uname, x, y);
}

demo();// undefined undefined undefined

demo.myBind(obj, 1, 2)();
// Tom 1 2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值