zl程序教程

您现在的位置是:首页 >  后端

当前栏目

前端知识点:函数/箭头函数/class实例中this的指向

实例知识点前端 函数 Class this 指向 箭头
2023-09-11 14:22:32 时间

描述

请思考以下代码段的执行结果(可以拷贝到浏览器控制台运行哦):

window.name = 'win';

let temp_x1 = {
  name: 'x1',
  print1: function() { console.log(this.name); },
  print2: () => console.log(this.name)
};

class temp_xx {
  name = 'xx';
  constructor(name) { this.name = name; }
  print1 = function() { console.log(this.name); }
  print2 = () => console.log(this.name);
  print3 = function() {
    return (
      () => console.log(this.name)
    )();
  }
}
let temp_x2 = new temp_xx('x2');

temp_x1.print1();
temp_x2.print1();
temp_x1.print1 = temp_x2.print1; 
temp_x1.print1();
console.log("*********");

temp_x1.print2();
temp_x2.print2();
temp_x1.print1 = temp_x2.print2;
temp_x1.print1();
temp_x2.print1 = temp_x1.print2;
temp_x2.print1();
console.log("*********");

temp_x2.print3();
temp_x1.print1 = temp_x2.print3;
temp_x1.print1();

实际输出结果

x1
x2
x1
*********
win
x2
x2
win
*********
x2
x1

结果解析

首先,从箭头函数中this的指向这篇博文我们可以得知:

①普通函数的this与其定义位置无关,谁调用这个函数,this就指向谁
②箭头函数的this与调用者无关,定义位置所在的作用域的this(函数作用域)是谁,箭头函数的this就指向谁

所以,在示例代码中,print1(普通函数)输出的name总是调用它的对象中name的值
而print2(箭头函数)输出的name总是定义位置所在作用域中name的值

  1. 接下来详细分析print2的输出结果:
  • temp_x1中定义的print2始终指向temp_x1所在的作用域,即window对象(还不了解js中作用域概念的话,可以看这篇JS中的变量作用域),将它赋值给temp_x2也不会改变其指向
  • temp_xx中定义的print2默认指向类的实例(参见ES6-class),在示例代码段中即为temp_x2对象,将它赋值给temp_x1也不会改变其指向
  1. 最后分析print3的输出结果:
  • temp_xx中定义的print3是一个普通函数,即:print3的this始终指向调用者;而其中返回的箭头函数this的指向始终与print3一致,即:指向print3的调用者;所以谁调用print3,输出的就是谁的name

参考文档

[1] 箭头函数中this的指向
[2] JS中的变量作用域
[3] ES6-class