一句话:改变调用方法的this指向,示例以下:bash
function a(){
console.log(this);
}
a();
a.call({name:"西瓜"});
复制代码
能够看到,第一次this
指向了window
,第二次this
指向了传入的对象;app
先来看一个东西,或许就能明白函数
var a = {
name:"西瓜",
run:function(){
console.log(this);
console.log(this.name);
}
}
a.run();
复制代码
上面这段代码,相信小伙伴都能看懂,其实,call执行的时候,也是作了这样的处理;。学习
Function.prototype.MyCall = function(obj){
var newObj = obj || window;
newObj.fn = this;
var params = [...arguments].slice(1);
var result = newObj.fn(...params);
delete newObj.fn;
return result;
}
复制代码
就上面的这段代码,就实现了一个call的功能,来看下这段代码都作了哪些事情ui
obj
存在,则新对象等于obj
,若obj
不存在,则等于window
;fn
函数(即为要调用的函数);fn
删除;来验证一下是否正确this
function test(){
console.log(this);
}
test();
test.MyCall({name:"西瓜"});
复制代码
结果以下图: spa
function f1(a){
console.log(1);
console.log(this);
}
function f2(){
console.log(2);
console.log(this);
}
f1.call(f2);
f1.call.call(f2);
复制代码
想一下,这段代码打印出来的会是一个什么结果呢? prototype
f1.call(f2)
的打印结果,相信你们都能理解,这里就不解释了;重点来说一下
f1.call.call(f2)
; 首先,咱们用刚刚本身实现的call方法来试试,会不会出现一样的结果;
f1.MyCall(f2);
f1.MyCall.MyCall(f2);
复制代码
结果固然是同样的啦!以下: code
Function.prototype.MyCall = function(obj){
var newObj = obj || window;
newObj.fn = this;
var params = [...arguments].slice(1);
var result = newObj.fn(...params);
delete newObj.fn;
return result;
}
复制代码
当咱们执行f1.MyCall.MyCall(f2)
的时候,上面这个MyCall
方法中的this
和newObj
指的分别是什么? 个人理解是this
为f1.MyCall
,即为Function.prototype.MyCall
,newObj
为f2
方法; 所当f1.MyCall.MyCall(f2)
执行的时候,结果就变了如下结果:cdn
var newObj = f2;
f2.fn = Function.prototype.MyCall;
复制代码
接下来MyCall
的第5行是否是会执行newObj.fn
? 其实就是执行f2.MyCall()
这个结果你们应该都知道了吧;
若是说上面这个理解了,能够想一想下面几个会打印出什么内容:
f1.call.call.call(f2)
f1.call.call.call.call(f2)
f1.call.call.call.call.call(f2)
复制代码
其实都是同样的哈!
除了call
,还有两个相似的方法apply,bind
,这里就不作过多的解释了,相信小伙伴必定也能跟着这样的思路去手写出来。有什么问题就给我留言吧!