模拟实现 call, apply 方法

2021-03-07  本文已影响0人  弱冠而不立

先回顾一下 call, apply 方法

let bar = "123"
let obj = {
  bar: "zhongli"
}
function foo(msg, name) {
  console.log(this.bar, msg, name);
}

foo.call(obj, "wuwuuw", "77") 
foo.apply(obj, ["hahah", "keli"])

就好像,obj 有了 foo 这个函数属性一样。所以跟着这个思路,我们可以试着自己写一下:
(这里偷个懒,使用 es6 中的扩展运算符去处理参数。要不然就使用 arguments 遍历后去运行)

  1. 将这个对象作为参数,给它一个属性(随便取名字)
  2. 把当前调用我们自定义call, apply 的函数赋给这个属性
  3. 调用这个属性方法
  4. 使用 delete 操作符,删掉对象上这个随便取名的属性

myCall

Function.prototype.myCall = function(context, ...arg) {
    // 如果传入 null 的话, 则this指向undefined,非严格模式下就指向全局对象
    var context = context || window;
    // 因为是某个函数调用了我们自定义的方法,所以此刻的this就指向的是函数
    context.fn = this;
    // 传入参数,然后执行这个this指向的函数
    context.fn(...arg);

    // 删除这个,多余的属性
    delete context.fn;
}

// 测试一下
foo.myCall(obj, "wuwuuw", "77") 

myApply

思路和 自定义call方法是一样的,只是传参的方式不一样

Function.prototype.myApply = function(context, [...arg]) {
    var context = context || window;
    context.fn = this;
    context.fn(...arg);

    delete context.fn;
}
foo.myApply(obj, ["hahah", "keli"])
上一篇下一篇

猜你喜欢

热点阅读