javascript - 如果我不能访问它的输出,为什么我可以扩展箭头函数?
问题描述
给定以下示例:
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 中的定义有些模糊。
解决方案
编译或执行的东西并不意味着它是有效的或符合规范。所以你总是需要检查规范什么是有效的,什么是无效的。您的问题的相关部分可以在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
是一个带有 [[Construct]] 内部方法的函数对象。
ClassHeritage
定义如下:
ClassHeritage [Yield, Await]: extends LeftHandSideExpression[?Yield, ?Await]
推荐阅读
- node.js - 如何在 ubuntu 上使用 express static 将 html 文件带入我的 nodejs 文件?
- javascript - Ag-Grid 为单个 rowNode 启用复选框选择
- javascript - 如何在 Ionic 中将画布保存为 jpg?
- openssl - BIO_meth_new + BIO_get_new_index 的正确用法是什么?
- sql - Redshift - 过去一小时的值的窗口函数
- python - 为什么这个while循环结束?node5 不是 NoneType。(遍历链表)
- hive - 在 HIVE 中插入当前时间戳作为多行插入的一部分
- merge - SSIS - 加入来自不同服务器的两个不同表
- wordpress - Laravel 使用 wordpress 博客从公共文件夹中安装
- batch-file - 在批处理文件中拖放-扩展此代码问题的变量