this的指向详解

146 阅读2分钟

这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

this关键字在js中,最重要的还是它的指向问题,在什么情况下它代表着什么。this的指向主要还是跟调用它的方式有关系;调用它的方式主要有:函数调用、构造函数调用、对象调用这三种方式;我记得有这样的一句话:谁调用,this就指向谁。

函数调用

var student = '小明';
function person() {
    console.log(this.student);
}
person(); // 小明

上示代码中,在全局作用域里声明了一个变量student和一个函数person;在下面调用的函数person,咋一看,好像是没有谁执行了调用函数操作,其实不是的,在全局作用域中声明的变量、函数都属于全局对象widows的变量和方法,而在这里的调用person()也其实就是windows.person()的简写,所以呢,调用这个函数就是windows在调用,this也是指向windows。

构造函数调用

function Person(name) {
    this.name = name;
}
let student = new Person('小明');
console.log(student.name); // 小明

上示代码中,有一个构造函数Person,函数里面有一个属性name;但是,为啥console.log(student.name)能打印出小明?student有name属性?因为在let student = new Person('小明')中,关键字new通过构造函数Person新建了一个实例对象(这里的新建实例对象其实就是根据构造函数Person复制出一个新的对象),并将构造函数的this指向这个新的实例对象;然后再将这个实例对象赋值给了student,所以student有name属性,在new实例对象的时候将‘小明’传进去,自然就能打印出‘小明’了。

对象调用

let obj = {
  name: '小明',
  fn: function() {
    console.log(this.name)
  }
}
obj.fn() // 小明

上示代码中,声明了一个对象obj,obj里面有name、fn两个属性,其中fn属性是一个方法;在下面的方法调用中,是obj调用了fn方法,所以函数fn的this指向obj,自然而然的就能打印出obj的name属性。假如我们把这段代码稍微的改动一下,如下所示:

let obj = {
  name: '小明',
  fn: function() {
    console.log(this.name);
    console.log(this)
  }
}
let student = obj.fn;
student();

在这次的调用中,就打印不出来‘小明’了,因为此时调用函数的就不是obj了,是全局对象windows;因为在let student = obj.fn中,我们已经把函数复制给了变量student,然后执行Windows.student(),所以函数里面的this指向全局对象windows。