javascript call方法的用处及原理

call的做用

一句话:改变调用方法的this指向,示例以下:bash

function a(){
	console.log(this);
}
a();
a.call({name:"西瓜"});
复制代码

能够看到,第一次this指向了window,第二次this指向了传入的对象;app

那么在执行call方法的时候,内部作了什么处理呢?

先来看一个东西,或许就能明白函数

var a = {
	name:"西瓜",
	run:function(){
		console.log(this);
		console.log(this.name);
	}
}
a.run();
复制代码

上面这段代码,相信小伙伴都能看懂,其实,call执行的时候,也是作了这样的处理;。学习

手动来实现一个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

  1. 定义一个新的对象,若传入的obj存在,则新对象等于obj,若obj不存在,则等于window
  2. 把this挂在到当前定义的新对象上(this即为调用的函数);
  3. 第4行代码处理了函数的传参;
  4. 而后执行建立的新对象的fn函数(即为要调用的函数);
  5. 最后在执行了之后,把这个挂载的fn删除;

来验证一下是否正确this

function test(){
	console.log(this);
}
test();
test.MyCall({name:"西瓜"});
复制代码

结果以下图: spa

能够看到,结果和使用call的时候输出的一致。这样就本身手动实现了一个call方法;

接下来,讲一个我在学习call的时候,网上常常讲到的一个案例,咱们一块儿来看一下:

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

为何会这样呢,来谈谈我对这个结果的理解吧(可能其余小伙伴有更好的理解)! 把上面本身实现的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;
}
复制代码

当咱们执行f1.MyCall.MyCall(f2)的时候,上面这个MyCall方法中的thisnewObj指的分别是什么? 个人理解是thisf1.MyCall,即为Function.prototype.MyCallnewObjf2方法; 所当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,这里就不作过多的解释了,相信小伙伴必定也能跟着这样的思路去手写出来。有什么问题就给我留言吧!

相关文章
相关标签/搜索