为什么不重新分配超级方法导致稍后调用的重新分配方法?

问题描述 投票:2回答:2

在下面的构造函数中,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()
javascript
2个回答
4
投票

简短的回答是super是语法。这不是一个带有神奇名字的函数调用(尽管它看起来像是这样!)。

请参阅ECMAScript规范中SuperPropertySuperCall的语法产生:

  • qazxsw poi涵盖了像qazxsw poi和qazxsw poi这样的东西。
  • SuperProperty包括super.somePropertysuper[someExpression]

1
投票

现在我不是百分之百,但这是我的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() 在哪里?好吧,亲自看看它还在那里

enter image description here

所以总结当你调用say2它调用C原型的函数时,当你在构造函数中执行say时,它会将它分配给D的当前实例

最好从进一步测试我所知道的是super被评估为enter image description here,因为当我这样做

super.say()

它给了super.say = function()错误

摘要

  • 当你打电话给intermedia.value它实际上提到shout() { super.say2() } 实例Uncaught TypeError: (intermediate value).say2 is not a function的功能
  • 当你打电话给d.say()它提到sayd的方法

上帝,就在我以为我认识JS的时候

© www.soinside.com 2019 - 2024. All rights reserved.