Published on

通过call轻松理解this

Authors

在javascript中的一个重大的难点就是对this的理解,因为javascript虽然是一种词法作用域的语言,但里面的this却似乎总是在变化中的,我们很难有一个既定的规则来描述在表示的是什么。同时它也未非像它的字面意思那样,表示指向当前函数。

比如

var a = 1;
function test(){
	var a = 2;
	console.log(this.a);
}
test();//1

从字面上来理解,也许this.a表示test中的a更容易让我们授受,反而结果却并不是这样的。这也就是为什么在ES6中会出现=>符号的原因了。

借力,也许是最轻松的办法,在这里,也许我们通过借力js中的call方法能够让我们更轻松地弄清楚js中的this在各种情况之下的指向。

一.call的本来面目

我们知道,js中的call就是改变一个对象的引用,它可以修改函数中的this引用。这点就可以让我们很轻松地明白了,你call了什么,this就是代表的什么了。


function show(b){
	console.log("a:"+this.a+" b:"+b);
}
var a = 1;
var obj1 = {
	a:2
};
var obj2 = {
	a:3
};
show.call(obj1,4);//a:2 b:4
show.call(obj2,4);//a:3 b:4

二.没有call,call依然存在

function show(b){
	console.log("a:"+this.a+" b:"+b);
}
var a = 1;
var obj1 = {
	a:2
};
var obj2 = {
	a:3
};
show(4);//a:1 b:4
show.call(window,4);//a:1 b:4

换一个思路来理解这段代码,其实show(4)也就是相当于show.call(window,4); 也就是说,直接执行函数的时候,其实就是call了一个window对象进去。只是我们把它给简写了而已。

三.隐式调用

function show(b){
	console.log("a:"+this.a+" b:"+b);
}
var a = 1;
var obj = {
	a:2,
	show:show
}
obj.show(3);//a:2 b:3
show.call(obj,3);//a:2 b:3

看得出,在对象的执行上下方下中的代码,其obj.show(3)也就相当于show.call(obj.3)

四.当有了new

var a = 1;
function show(a){
	this.a = a
}
var b = new show(2);
console.log(b.a);//2

我们知道,new操作符是新生成一个实例对象出来,这里的操作其实也就是有点类似于var b = {},当new了之后,其执行上下文也就是在b中了,所以它的指向也就是b了,和上面第三点的隐似调用非常类似。