在下面的构造函数中,super.say
被重新赋值给一个新函数。在实例上调用.say()
时,将调用新函数。但是当在调用super.say
的实例上调用另一个方法时,不会调用新函数 - 而是调用父C
类上的原始函数。为什么会有区别?
class C {
say() {
console.log('hello');
}
}
class D extends C {
constructor() {
super()
super.say = function() {
console.log('changed');
}
}
shout() {
super.say()
}
}
let d = new D()
// changed
d.say()
// hello
d.shout()
简短的回答是super
是语法。这不是一个带有神奇名字的函数调用(尽管它看起来像是这样!)。
请参阅ECMAScript规范中SuperProperty
和SuperCall
的语法产生:
SuperProperty
包括super.someProperty
和super[someExpression]
。现在我不是百分之百,但这是我的2美分发生了什么
SuperCall
表现得非常奇怪,从它的外观来看,super()
在不同的操作中表现出不同的东西,而这正是发生的事情。怀疑它早些时候我试图super(someArgument)
和错误发生。当我用Google搜索找到原因?我发现了解释,沿着“它像super
这样的super
,你不能记录console.log(super)
关键字,因为它是”。所以这告诉我们keyword
不是你的常规对象。
当你做某些事情时会发生什么
var
这里var
实际上会调用原型C的构造函数,你可以看到当你super
导致
constructor() {
super();
}
但是一旦你做到了
super()
在这里,console.log(C)
实际上指的是C = {
constructor: f(),
say: f()
}
或D级的实例(Bejesus的圣母,怎么能有人这样的东西逃脱)
我将名称更改为class D extends C {
constructor(id) {
super();
super.say2 = function() {
console.log('changed ' + this.id);
}
}
以确切地验证,请参阅下面的代码,我将其更改为测试
super.say2
当您运行此代码时,您将在控制台中看到的内容
this
这里say2
实际上是D的实例,C原型的class C {
say() {
console.log('hello');
}
}
class D extends C {
constructor(id) {
super();
super.say2 = function() {
console.log('changed ' + this.id);
}
console.log(this)
console.log(D.prototype)
}
shout() {
super.say()
}
}
let d = new D(1)
d.say()
d.shout()
在哪里?好吧,亲自看看它还在那里
所以总结当你调用say2
它调用C原型的函数时,当你在构造函数中执行say
时,它会将它分配给D的当前实例
最好从进一步测试我所知道的是super被评估为,因为当我这样做
super.say()
它给了super.say = function()
错误
摘要
intermedia.value
它实际上提到shout() {
super.say2()
}
实例Uncaught TypeError: (intermediate value).say2 is not a function
的功能d.say()
它提到say
类d
的方法上帝,就在我以为我认识JS的时候