先回顾一下 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 遍历后去运行)
- 将这个对象作为参数,给它一个属性(随便取名字)
- 把当前调用我们自定义call, apply 的函数赋给这个属性
- 调用这个属性方法
- 使用 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"])
网友评论