this指向问题

60 阅读2分钟

this指向简单实践

  • 1.在构造函数里,this指向调用他的实例对象
  • 2.构造函数自身上的函数指向构造函数本身(也可理解为this指向最后调用者)
  • 3.在setTimeout等window上的方法里,this指向window, 因为最后调用者是window.前提是setTimeout里的回调函数为普通函数, 如果是箭头函数则不一定指向window
  • 4.箭头函数this指向它定义时的执行期上下文
export function Person(name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
  this.obj = {
    speakThis: function() {
      console.log(this, 'this指向obj'); // 普通函数, this指向最后调用者(obj的实例)
      setTimeout(() => {
        console.log(this, 'this指向obj'); // this指向obj, 也可以理解为箭头函数this指向===离它最近的父级this的指向
      }, 0);
      setTimeout(function() {
        console.log(this, 'this指向window'); // setTimeout是window的方法, 里面的回调函数如果是普通函数, this指向window(也可以理解为window是setTimeout最后调用者)
      }, 0);
    },
    speakThis2: () => {
      console.log(this, 'this指向实例对象'); // 箭头函数this指向实例对象
      setTimeout(() => {
        console.log(this, 'this指向实例对象'); // this指向实例对象, 也可以理解为箭头函数this指向===离它最近的父级this的指向
      }, 0);
      setTimeout(function() {
        console.log(this, 'this指向window'); // setTimeout是window的方法, 里面的回调函数如果是普通函数, this指向window(也可以理解为window是setTimeout最后调用者)
      }, 0);
    },
  };
  this.sayHello = function() {
    console.log(' hello', this.name, 'this指向实例'); // 普通函数, this指向最后调用者(Person的实例)
  };
  this.sayHello2 = () => {
    console.log(' hello2', this.name, 'this指向实例');
    // Person.speakHaha();
    // Person.speakName(name);
    // Person.prototype.speakAge(age);
  };
}

Person.speakName = function(name) {
  console.log('我是' + name);
  console.log(this === Person, 'this指向构造函数'); // this指向最后调用者(Person)
};

// 放在原型上的方法,根据调用方式的不一样,this指向也不一样
Person.prototype.speakAge = function(age) {
  console.log('我今年' + age + '岁了');
  // 调用方式 p1.__proto__.speakAge(12)  p1为实例对象
  console.log(this === Person.prototype, 'this指向原型对象', this); // 实例对象.__proto__.speakAge(12) this指向最后调用者(prototype)
  // 调用方式 p1.speakAge(12)  p1为实例对象
  console.log('this指向实例对象', this); // 实例对象.speakAge(12) this指向最后调用者(实例对象)
};

Person.speakHaha = () => {
  console.log('haha', this); // this指向undefined, 该构造函数声明在文件最外层, 打包之后放在Module里, 而Module的this指向undefined
};

Person.prototype.speakAge2 = age => {
  console.log('我今年' + age + '岁了');
  console.log('this指向 === 原型对象里的this === undefined', this); // this === Person.prototype.this === ubndefined (纯属个人猜想)
};

测试调用

import { Person } from '../../tools';
const p1 = new Person('sandy', 23, 'girl');
    // p1.sayHello2();
    // p1.speakAge(12); // 最后调用者p1
    // p1.__proto__.speakAge2(12); // 最后调用者p1.__proto__
    // p1.speakAge2(12);
    // p1.obj.speakThis2();