javascript - 如果原始子类方法已在子类中被重写,如何访问该方法?

标签 javascript mongodb

我通过用我自己的版本扩展原始类和通过覆盖原始类的方法来替换一些内置的javascript类。但是,有时我在覆盖的方法中想访问原始方法。但是,javascript只允许我执行某些操作,而其他时候则不允许。这是非常不可预测的行为,我不知道它是怎么回事。似乎每次调用具有相同参数的相同方法时,其结果都不同。

这是我修改并得到这种奇怪行为的一个javascript内置类和方法的示例:

//Inherit everything from original String class in STRING class.
class STRING extends String
{
    //Redefine behavior of original replace method.
    replace()
    {
        //Get original javascript's replace method definition from prototype
        //of this class's prototype (base class) and attach it to this
        //object's instance, and then run it and pass anything it returns
        //back to the caller.
        return this.__proto__.__proto__.replace.call(this);
    }
}
//Replace original javascript's replace method with custom replace method
//everywhere, including in string primitives.
String.prototype.replace = STRING.prototype.replace;
//Replace whole original javascript's String class with custom STRING class.
String = STRING;
//Create custom string primitive.
let a = "hello stacky";
//Call custom replace method in custom string primitive.
a.replace();


这段代码本质上的作用是,仅将默认的javascript的String类和replace方法传递给我的自定义类和方法,就可以执行它的任何工作。 (如代理)。

请忽略某些内容丢失,并且此代码是毫无意义的,因为它什么也不做。我只是简化了它,以便能够向您显示问题。因此,我知道String方法应该有两个参数,但现在让我们忽略它。即使没有参数,它也可以工作(当没有给出参数时,replace方法与replace方法相同)。

在将toString类定义为STRING类的扩展之后,我将String方法复制到replace原型,因为否则,只有StringSTRING对象将具有该方法,而没有String原语。

然后,我创建测试原语,并在其上调用我的自定义string方法。

这应该输出replace,因为如果在不带参数的情况下调用hello stacky上的replace方法将与调用STRING方法相同。

toString方法中,以下语句应该为true,有时是,有时不是:


首先,调用replace,它返回this对象。
之后,首先调用STRING访问器。这应该返回该__proto__对象的原型,这是我的自定义STRING类。
接下来,调用第二个STRING访问器。这应该返回该对象的原型的原型。因此,由于__proto__对象的原型是STRING类,因此第二个STRING应该返回__proto__类的原型。那应该是原始javascript的STRING类。
接下来,调用String方法。由于第二个replace应该返回__proto__类,因此该String方法应该是原始javascript的replace方法定义。
最后,replace方法被称为call方法,并且replace对象的上下文被提供给该方法。这应将原始javascript的this方法附加到此字符串,执行该字符串,并将其结果返回到replace类中的自定义replace方法中。
然后,自定义STRING方法将其从被调用方法获得的所有内容返回给调用方。因此,输出应等于hello stacky。


但是,这并非每次都起作用。当它不起作用时,以下是正确的:


replace引用当前的this对象。
STRING也指当前的this.__proto__对象。
STRING也以某种方式引用当前的this.__proto__.__proto__对象。
STRING是指this.__proto__.__proto__.__proto__


我也尝试使用Object而不是replaceString类访问super,但是它仍然无法访问正确的方法。

昨天我执行了此代码,并返回了this.__proto__.__proto__
今天,相同的精确代码返回hello stacky

我知道我可能在这里错过了一些东西,但是,不知道是什么。或MongoDB无法正常工作。

我真的不知道发生了什么。

我明白了,在我的代码中有以下一行:typeError: this.__proto__.__proto__.replace is undefined:.这很棘手,因为String=STRINGSTRING的子类,这可能导致String类被完全清除并替换为String类,是它自己的父母。
根据STRING类,this.__proto__.__proto__类是其自己的父类,因为STRING类的原型是另一个STRING类,并且该STRING类的原型是STRING类,而不是Object类。

但是,如果是这样的话,为什么它昨天仍然有效?

好吧,确切地说,不是我在这里编写的确切代码。并非昨天的代码有效。但是,我有另一种方法的代码,自昨天以来我从未真正对其进行过修改,而昨天它仍然有效,但今天却没有。
在这里的这个示例中,我删除了99%的代码,但是保留了对该问题很重要的部分。此代码确实产生与我的原始代码相同的错误。这就是为什么我说“此”代码昨天有效。

您可能要知道的重要一点是我如何测试此代码。
为了进行测试,我使用了mongodb shell。

另外,重要的是要提到我正在使用mongodb 4.1.6版(即beta版),因此使用的是不稳定版本的mongo。这可能是这种奇怪行为的根源。

因此,我对您的问题是:为什么这段代码昨天无法使用,但是今天不再可用?
如果您不能回答这个问题,那么您能告诉我应该怎么做才能正确完成此任务?

任务是:
定义必须重写String方法的String类的子类,并确保每个字符串实例,无论使用replace构造函数,STRING构造函数或String创建的天气如何,都具有相同的自定义行为调用""方法时。

最佳答案

不知道您要在这里完成什么-记录下来,这似乎是一个Bad Idea™-但是,如果必须的话,您是否考虑过使用super



class Wookie extends String {
  replace(...args) {
    return super.replace.apply(this, args);
  }
}

const wookie = new Wookie("chewbacca");
console.log(wookie.replace('c', 'b'));

关于javascript - 如果原始子类方法已在子类中被重写,如何访问该方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56232623/

相关文章:

javascript - csv-parse 解析的对象的第一个属性不可访问

javascript - window.matchMedia 的 AddEventListener 无法正常工作 javascript

javascript - 如何在不知道元素 ID 的情况下单独替换元素?

java - 可能 MongoDB 和 HttpUrlConnection 资源冲突?

php - 在 php xampp ubuntu 中找不到类 'MongoClient'

javascript - 为什么clearInterval不清除setInterval定时器

javascript - 修复联系表格 - 消息发送成功

python - 删除 find().limit() 返回的所有文档

c#-4.0 - '意外元素 : XX' during deserialization MongoDB C#

mongodb - 使用以前的/data/db 内容的普通备份启动 mongodb