this的指向问题

我心飞翔 分类:javascript

前言:js中经常会看到this.,在不理解this的时候就会造成this的“滥用”,导致开发过程中需要花费大量的时间查找因为this的指向问题导致的bug。希望通过本文能够让大家理解this,节省大家开发时间。

1、什么是this

this是当前执行代码的环境对象,如果在非严格模式下,总是指向一个对象;如果在严格模式下,可以是任意值。
在不同的情况下this的指向也有所不同,接下来我们看一下几种不同情况下this的指向。

2、不同情况下this的指向

  • 全局环境

全局环境中,this指向全局对象(本文只讨论在浏览器环境,不讨论nodejs):

console.log(this === window); // true
 
  • 函数环境

函数环境中,this的值取决于函数被调用的方式,也可以理解为函数由谁调用,this就指向谁:

function f1() {
    return this;
}
console.log(f1() === window); // true
 

f1()调用的时候相当于window.f1(),这里是省略了window。

  • 对象方法中

当函数作为对象中的方法被调用时,this是调用该函数的对象:

var user = {
    age: 31,
    getAge: function() {
        return this.age;
    }
}
console.log(user.getAge()); // 31
 

this是在getAge函数中,getAge又是被user调用,所以getAge中的this就指向了user,this.age也就是user.age。

  • 原型链中

如果this所在的方法存在于原型链中,那么this也是指向该方法的调用对象:

var util = {
    sum: function() {
        return this.a + this.b;
    }
};
var _util = Object.create(util);
_util.a = 1;
_util.b = 2;
console.log(_util.sum()); // 3
 
  • 构造函数中

当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象:

function userConstructor() {
    this.age = 33;
}
var user3 = new userConstructor();
console.log(user3.age); // 33
function userConstructor2() {
    this.age = 34;
    return {
        age: 35
    }
}
var user4 = new userConstructor2();
console.log(user4.age); // 35
 

对于user3.age这个很好理解,而user4中构造函数里直接返回了一个对象,这里如果构造函数中直接返回一个对象,那么通过new关键字创建出来的对象就是return的那个值,所以user.age值为35。

  • 箭头函数中

箭头函数中,this与封闭词法环境的this保持一致:

var user4 = {
    name: 'tom',
    age: 20,
    getName() {
        console.log(this.name);
    },
    getAge: () => {
        console.log(this.age);
    }
}
user4.getName(); // tom
user4.getAge(); // undefined
 

getName不是用的箭头函数,所以getName中的this指向该函数的调用者user4,this.name也就相当于user4.name;
但是getAge是一个箭头函数,它里面的this指向该函数所在的作用域,根据作用域相关的知识可以知道getAge应该在全局环境中,所以this指向window,这里假设全局环境没有age变量,所以this.age的值就为undefined。

3、如何改变this的指向

虽然this的指向有一定的规则,但是我们也可以主动的修改它的指向,以下三种方法可以修改this:

  • call
  • apply
  • bind

这三种方法可以指定this,具体怎么使用就不再多说,大家可以自行搜索学习。

4、总结

this的指向是前端的一个比较不好理解的知识点,但是一旦理解了this,对我们在平时开发过程中有很大的帮助,能够减小项目出现bug的几率,节省开发时间。

回复

我来回复
  • 暂无回复内容