7

为什么 ArrowFunction 不能 new

 3 years ago
source link: https://blog.jiejiss.com/%E4%B8%BA%E4%BB%80%E4%B9%88-ArrowFunction-%E4%B8%8D%E8%83%BD-new/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

0x00 TL;DR#

因为 Lexical this 导致没有 [[Construct]],所以不能 new

0x01 详细版本#

如果去查一下 ECMA spec,其实可以看到如下的解释:

A function object is an object that supports the [[Call]] internal method. A constructor is an object that supports the [[Construct]] internal method. Every object that supports [[Construct]] must support [[Call]]; that is, every constructor must be a function object. Therefore, a constructor may also be referred to as a constructor function or constructor function object.

所以想要对某个对象使用 new,就得确保该对象具有 [[Construct]] 这个内部方法。而 ArrowFunction 没有 [[Construct]]

再多查一点的话,可以在 14.2.17 这一节看到如下的注解:

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment.

再多查一点的话,可以找到最终通过的 proposal:https://tc39wiki.calculist.org/es6/arrow-functions/

The goal of Arrow Functions is to address and resolve several common pain points of traditional Function Expression:

  • Lexical this binding;
  • Shorter syntactical form (() => {} vs. function () {})

Lexical this matches the dominant cohort measured by Kevin Smith (see the BTF Measurements thread that either does not use this or wants it lexically bound.

  • Best results after modifying subject code to use method definition shorthand and only then scanning for function.
  • From lexical this it follows that arrow functions are not constructors (no .prototype or [[Construct]]).

再多查一点的话,你可以在 2011 年的一次讨论里找到这个设计的来源:https://mail.mozilla.org/pipermail/es-discuss/2012-March/021953.html

We do not want to delegate to a target function that can [[Construct]], because there is no such target function -- we're not trying to sugar .bind on a full function. That is too expensive and general (no pre-args, no full function under the hood).

Lexical-only this binding means no [[Construct]] and no .prototype for arrow functions. I'm ok with this.


考虑典型的代码如下:

class A {
constructor() {
this.attr = 0;
}
}

const a = new A();

// or

function A() {
this.attr = 0;
}

const a = new A();

在这两种构造实例的方法中,this 指向的都是正在被操作的变量 a。 但是 arrow function 在还是个草案的时候就只计划支持 Lexical this,因此它的函数体中的 this 不会指向正在被操作的变量 a,无法修改赋值表达式的左值,因此就算 ArrowFunction[[Construct]] 内部方法也无法用于构造新对象。

来源:https://blog.jiejiss.com/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK