首页 > 解决方案 > 如果我不能访问它的输出,为什么我可以扩展箭头函数?

问题描述

给定以下示例:

class X extends (() => {
  return "spam"
}) {
  constructor() {
    super() // Can't access
    this.msg = X() // Can't access
  }
}

let x = new X()
console.log(x.msg)

如果我不能访问它的输出,为什么我可以扩展箭头函数?记录的是:

error: Uncaught TypeError: Cannot call a class as a function

考虑到“新”的 ES6 定义,什么是类和什么是函数在 Javascript 中的定义有些模糊。

标签: javascriptecmascript-6

解决方案


编译或执行的东西并不意味着它是有效的或符合规范。所以你总是需要检查规范什么是有效的,什么是无效的。您的问题的相关部分可以在14.6.13 Runtime Semantics: ClassDefinitionEvaluation中找到:

[...]
5. If ClassHeritageopt is not present, then
   a. Let protoParent be the intrinsic object %ObjectPrototype%.
   b. Let constructorParent be the intrinsic object %FunctionPrototype%.
6. Else,
   a. Set the running execution context's LexicalEnvironment to classScope.
   b. Let superclassRef be the result of evaluating ClassHeritage.
   c. Set the running execution context's LexicalEnvironment to lex.
   d. Let superclass be ? GetValue(superclassRef).
   e. If superclass is null, then
      i. Let protoParent be null.
      ii. Let constructorParent be the intrinsic object %FunctionPrototype%.
   f. Else if IsConstructor(superclass) is false, throw a TypeError exception.
[...]

并且 6.f 状态Else if IsConstructor(superclass) is false, throw a TypeError exception.和箭头函数不是构造函数。

所以在评估类定义时,引擎需要TypeError根据规范抛出错误。

而 Chrome (76) 实际上在let x = new X()es 评估之前抛出了错误:

Uncaught TypeError: Class extends value () => { return "spam" } is not a constructor or null


7.2.4 IsConstructor(参数)

是一个带有 [[Construct]] 内部方法的函数对象。

ClassHeritage定义如下:

ClassHeritage [Yield, Await]:
   extends  LeftHandSideExpression[?Yield, ?Await]


推荐阅读