很多人遇到函数中this指向的问题会分辨不清,因此写下这篇文章,方便记忆理解。
普通函数中的this问题:
结论:this 永远指向 调用函数 的对象。
直接通过代码进行分析,举例如下:
例1:
function test(){
var a = 1;
console.log(this.a);
}
test(); //undefined
例1代码执行了test方法,结果并没有打印出方法内定义的局部变量a,而是打印了undefined。因为此时test是window对象的方法,里面的this指向了window。
例2:
var b = 2; //window对象下的变量
function test(){
var b = 1;
console.log(this.b);
}
test(); // 打印结果为 2
例2在window下声明了变量b,因此最后打印出了2。
下面是一个更加复杂的例子:
例3:
var name = 'China';
var obj = {
name : 'America',
show : function() {
console.log(this.name)
}
}
obj.show(); // America
上面的的例3中,obj的show方法执行后打印出America,很显然show方法里面的this指向了obj对象(也就是show方法的调用对象)。
例4:
var name = 'China';
var obj = {
name : 'America',
show : function() {
return function(){
console.log(this.name);
}
}
}
var a = obj.show();
a(); // China
上面的例4中show方法执行后,返回了一个匿名函数,a方法定义在window下,因此里面的this指向window,打印出window下的变量name。
箭头函数中的this问题:
箭头函数是函数的简洁写法,但是它的this问题和普通函数还是有所不同。
结论:箭头函数的this指向它所在作用域里面的对象。
例5:
var name = 'window_name';
var A = {
name: 'A',
sayHello: () => {
console.log(this.name)
}
}
A.sayHello();//window_name
上面的例5中出现了箭头函数,最后的打印结果是window_name,因为A是声明在window下,箭头函数所在的作用域下的对象是window,因此输出window下声明的name变量。
那么如何使得this指向对象A呢?可以使用以下的方式:
例6:
var name = 'window_name';
var A = {
name: 'A_name',
sayHello: function(){
var s = () => console.log(this.name)
return s//返回箭头函数
}
}
var sayHello = A.sayHello();
sayHello();// 输出A_name
var B = {
name: 'B_name';
}
sayHello.call(B); //还是A_name
sayHello.call(); //还是A_name
箭头函数的this,在定义完成的时候就确定了。箭头函数所在的作用域是sayHello函数内的作用域,里面的this指向A,因此后面即使有改变this指向的call,仍然不会影响最后的结果。
例8:
var name = "zhansan";
function Person() {
//this指向实例one
var s = () => {
console.log(this.name); //lisi
}
this.fn = s;
}
const one = new Person();
one.name = "lisi";
one.fn();
上面的例8可以辅助理解上面的结论。