箭头函数与普通函数的 this 和 new 行为

箭头函数和普通函数在 this 绑定和构造函数调用上的区别

问题

下面代码的输出是什么?

const obj = {
  fn1: () => console.log(this),
  fn2: function() {console.log(this)}
}

obj.fn1();
obj.fn2();

const x = new obj.fn1();

解答

obj.fn1() 的输出

箭头函数没有自己的 this,它会捕获定义时所在上下文的 this 值。在这个例子中,obj 对象字面量定义在全局作用域,因此 fn1 中的 this 指向全局对象 window(非严格模式)或 undefined(严格模式)。

输出:windowundefined

obj.fn2() 的输出

普通函数的 this 在运行时动态绑定。通过 obj.fn2() 调用时,this 指向调用者 obj。

输出:obj 对象本身

new obj.fn1() 的结果

箭头函数不能作为构造函数使用,因为它没有自己的 this,也没有 [[Construct]] 内部方法。

结果:抛出 TypeError: obj.fn1 is not a constructor 错误

由于这行代码报错,后续代码不会执行。

关键点

  • 箭头函数的 this 在定义时确定,继承自外层作用域,不会因调用方式改变
  • 普通函数的 this 在调用时确定,取决于调用方式
  • 箭头函数不能用作构造函数,使用 new 调用会抛出 TypeError
  • 普通函数可以用作构造函数,new 调用时 this 指向新创建的实例