- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图弄清楚我在 Node v4.1.1 (V8 v4.5.103.33) 中看到的一些关于 super
的行为和箭头函数是指定的行为,如果是(或者实际上,如果不是),它在 specification 中的位置它说它应该(或不应该)在我遇到的各种情况下工作。
简而言之:使用 super
在箭头函数 ( inner
) 内另一个箭头函数 ( outer
) 在方法内有效,除非 outer
有参数或变量 inner
引用,即使 inner
引用 method
的参数或变量.我想知道规范说明关于这一点:它是否应该一直工作,即使 V8 出现故障?没有时间?仅在 V8 当前允许它工作的特定情况下,而不是在它不工作的地方?
这是一个 MCVE:
"use strict";
class Parent {
show(msg) {
console.log(`Parent#show: ${msg}`);
}
}
class Child extends Parent {
method(arg) {
let outer = (x) => {
console.log(`outer: x = ${x}`);
let inner = () => {
super.show(`arg = ${arg}, x = ${x}`);
};
inner();
};
outer(42);
}
}
new Child().method("arg");
$ node test.js/path/test.js:13 super.show(`arg = ${arg}, x = ${x}`); ^^^^^SyntaxError: 'super' keyword unexpected here at outer (/path/test.js:16:13) at Child.method (/path/test.js:18:9) at Object. (/path/test.js:22:13) at Module._compile (module.js:434:26) at Object.Module._extensions..js (module.js:452:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:475:10) at startup (node.js:117:18) at node.js:951:3
If you remove the reference to x
that's in inner
:
let inner = () => {
super.show(`arg = ${arg}`); // <== removed x from this
};
outer: x = 42Parent#show: arg = arg
To prove to myself that the "works" case wasn't that the functions were being optimized away, I returned them out of the method and called them. Here's that slightly-more complex case (note the comments); this version works:
"use strict";
class Parent2 {
show(msg) {
console.log(`Parent2#show: ${msg}`);
}
}
class Child2 extends Parent2 {
method(arg) {
let flag = Math.random() < 0.5;
console.log(`method called with ${arg}, flag is ${flag}`);
let x = "A"; // **A**
let outer2 = (/*x*/) => { // **B**
//let x = "C"; // **C**
let inner2 = () => {
super.show(`${x}: ${arg} (${flag})`);
};
return inner2;
};
return outer2;
}
}
let o = new Child2().method("arg");
console.log(`type of outer2: ${typeof o}`);
let i = o();
console.log(`type of inner2: ${typeof i}`);
i("B");
A
的行并取消注释
B
或
C
,它像 MCVE 一样失败。
outer
访问 super
没有问题.我不想用另一个大代码块来混淆这个问题,但是如果你添加 super.show(`outer: arg = ${arg}, x = ${x}`);
在 outer
的顶部,它工作得很好。 inner
使用 method
中的参数和变量(嗯,MCVE 只使用一个 arg),这很好,但只要 inner
尝试使用 outer
中的参数或变量,事情闹大了。 super
的各种不同的部分。和“基础对象”等,坦率地说,我只是不明白。
最佳答案
看来这确实是 V8 中的一个错误(现在是 fixed )。 请注意,如果没有嵌套箭头函数,它可以正常工作。
因此,如果我们要通过文字规范文本来查看这是否是一个错误,让我们从 super
开始。关键字本身:
12.3.5.3 Runtime Semantics: MakeSuperPropertyReference(propertyKey, strict)
The abstract operation MakeSuperPropertyReference with arguments propertyKey and strict performs the following steps:
- Let env be GetThisEnvironment( ).
- If env.HasSuperBinding() is false, throw a ReferenceError exception.
- Let actualThis be env.GetThisBinding().
- ReturnIfAbrupt(actualThis).
- Let baseValue be env.GetSuperBase().
- Let bv be RequireObjectCoercible(baseValue).
- ReturnIfAbrupt(bv).
- Return a value of type Reference that is a Super Reference whose base value is bv, whose referenced name is propertyKey, whose thisValue is actualThis, and whose strict reference flag is strict.
8.3.2 GetThisEnvironment ( )
The abstract operation GetThisEnvironment finds the Environment Record that currently supplies the binding of the keyword this. GetThisEnvironment performs the following steps:
- Let lex be the running execution context’s LexicalEnvironment.
- Repeat
a. Let envRec be lex’s EnvironmentRecord.
b. Let exists be envRec.HasThisBinding().
c. If exists is true, return envRec.
d. Let outer be the value of lex’s outer environment reference.
e. Let lex be outer.NOTE The loop in step 2 will always terminate because the list of environments always ends with the global environment which has a this binding.
this
,它应该跳过当前函数的环境记录和立即包含它的函数。
super
的引用。根据规范,对象符合预期。
super
is lexically scoped, just likethis
to the closest enclosing function that defines it. All function definition forms except for arrow functions introduce newthis
/super
bindings so we can just [say] thatthis
/super
binds according to the closest enclosing non-arrow function definition.
关于javascript - 在方法内的箭头函数内的箭头函数内使用 `super`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32943776/
问题比较Java,但是我想在Android中实现: 假设有 3 个或更多类相互扩展: class A { ... int color; ... } class B extend
我知道标题听起来有点奇怪,但这正是我愿意做的。简单解释:A类是B类的子类,B类也是C类的子类>. 现在,所有这些类都包含方法m()。在我的 A 类中,这是我唯一可以访问的类,因为其他类仅在运行时可用,
我有一个 UIViewController 类 A 和 B。 A 使用以下方式加载 B:[A.view addSubView B.view]。 B 有一个带有“后退”按钮的导航栏。我想在单击时返回到
我有以下(第三方)类结构。我们将调用第三方项目 ProjectSeriously,并注意我使用 System.out.println 代替其他复杂的功能(100 行代码) . class A {
在下面的代码中,我从 Game 扩展了 MyGame。我有两个问题: 我们是否需要为所有render()、dispose()、pause()调用super方法 和 resize(w,h)?很多人都没有
例如,假设我想在调用 super.viewDidLoad() 时跳过一级。所以我希望能够做这样的事情: override func viewDidLoad() { super.super.vi
public class Faculty extends Employee { public static void main(String[] args) { new Fac
假设我有: class Superclass { //fields... methodA() {...} methodB() {...} ... } class Subclass exte
这个问题在这里已经有了答案: Why is super.super.method(); not allowed in Java? (22 个答案) 关闭 9 年前。 我怀疑我想做的事情是否可行。我有
我有一个实现 Initializable 的类。 public abstract class ExampleClass implements Initializable { public vo
我想知道,我有这个大数组,是否可以只在内存中使用一次而不是每个线程一次?以 stackoverflow 上的标签为例。他们几乎从不改变,为什么不为他们留下一个内存点呢?甚至可能将该数组永久保存在内存中
假设这三个类具有这个简单的层次结构: class A { func foo() { print("A") } } class B: A { override fu
有没有办法在 TypeScript 中调用 super.super.methodName。我想避免调用super.methodName,但我想调用二祖的methodName方法。 谢谢。 最佳答案 T
这个问题已经有答案了: When do I use super()? (11 个回答) 已关闭 7 年前。 package Geometry; public abstract class Geomet
我必须执行and()在我的实现 Predicate 的业务对象上. 出现问题的代码是 and() 行调用: Predicate predicate = new M
我有一个实现接口(interface)的抽象父类(super class): public abstract class FooMatrix implements Matrix { publi
我有四个 UIView:viewA 是 Root View ,它有 viewB 作为它的 subview 。 viewB 将 viewC 作为其 subview ,而 viewC 将 viewD 作为
有什么区别: class Child(SomeBaseClass): def __init__(self): super(Child, self).__init__() 和:
我有一个通用接口(interface) interface ListList extends List> .由于某些原因,我无法转换 ListList至 List> .有什么方法可以做到吗?为什么它不
我想调用带有两个参数的父类(super class)的构造函数,所以我调用了 super(arguments),但是编译器说: “类 Person 中的构造函数 Person 不能应用于给定类型; 要
我是一名优秀的程序员,十分优秀!