What is the best way to call the original method of a base class that has been overridden in a derived class?

While working on some javascript code, I found myself extending built-in classes and overriding methods with my own versions. However, I encountered a problem where sometimes I needed to access the original methods within my overridden ones, but JavaScript did not always allow me to do so. This inconsistency led to unpredictable behavior that left me confused about what was happening.

An example of this inconsistent behavior can be seen in the modified replace method of a built-in JavaScript class:

//Extending the String class to create a new class called STRING.
class STRING extends String
{
    //Overriding the original 'replace' method.
    replace()
    {
        //Attempting to access the original 'replace' method by traversing the prototype chain. However, the results are not consistent.
        return this.__proto__.__proto__.replace.call(this);
    }
}
//Replacing the original 'replace' method with the custom one in the String prototype.
String.prototype.replace = STRING.prototype.replace;
//Replacing the entire String class with the custom STRING class.
String = STRING;
//Creating a custom string primitive.
let a = "hello stacky";
//Calling the custom replace method on the custom string primitive.
a.replace();

In essence, this code acts as a proxy for the default behaviors of the String class and its replace method, passing them through my custom implementation. Although seemingly unnecessary, this simplified example highlights the issue at hand.

Despite the missing elements and trivial nature of this code snippet, it serves its purpose in showcasing the problem I'm facing. We'll ignore the absence of parameters for the replace method for now, as the function behaves similarly to toString when called without arguments.

After defining the STRING class as an extension of String, I ensure that the replace method is available to all types of strings – constructed using STRING, String, or literal syntax.

The inconsistencies arise when attempting to access the original replace method from the String superclass within the extended STRING class definition.

  1. When the logic works as expected:
    • this points to the current instance of the STRING object.
    • this.__proto__ refers to the prototype of the STRING object.
    • this.__proto__.__proto__ should resolve to the prototype of the prototype, i.e., the original JavaScript String class.
  2. Contrastingly, when the behavior is erratic:
    • The chain of this.__proto__ references leads back to the Object class instead of the desired String class.

A failed attempt to access the correct method using super instead of manual chaining results in a typeError indicating undefined property.

These discrepancies have prompted confusion over why this code worked previously but now presents issues. Could it be related to the beta (unstable) version of MongoDB being used for testing?

The overarching task is to define a subclass of the String class that overrides the replace method while ensuring consistent behavior across all string instances. How can this goal be achieved effectively?

Answer №1

Not sure of the intention behind this approach — and for clarity's sake, it appears to be A Bad Idea™ — however, if necessary, have you pondered utilizing super?

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

const ewok = new Ewok("wicket");
console.log(ewok.replace('w', 'b'));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on setting a client-side cookie in NextJS 14

I attempted to store a cookie in the client's browser using Nextjs 14 app router within the API folder, but unfortunately, it did not function as expected Below is the provided code snippet: app/api/auth/login/route.js const { NextResponse } = requi ...

Display routes in React using the react-router package

Can I use a console command at runtime to display all routes in my application? Despite utilizing react-router, not all routes seem to be functioning properly. In Rails, you can retrieve a list of routes during runtime. ...

Attempting to clear the value of a state property using the delete method is proving to be ineffective

Within my React-component, there exists an optional property. Depending on whether this property is set or not, a modal dialog is displayed. Therefore, when the modal should be closed/hidden, the property must not be set. My state (in simplified form): i ...

When multiple update calls are made simultaneously on the same document in MongoDB, the updateOne() function will return a "modifiedCount" of 1

Our focus is on updating a document by utilizing the updateOne() method. The filter criterion pinpoints the specific document, and we modify an attribute of that document using $set. This update task is triggered every minute by a cron job. Assume the ini ...

Updating the DOM after making changes with Maquette involves calling the `renderMaquette

In a previous discussion, I expressed my desire to utilize Maquette as a foundational hyperscript language. Consequently, avoiding the use of maquette.projector is essential for me. However, despite successfully appending SVG objects created with Maquette ...

Testing the jQuery UI datepicker with QUnit: A Step-by-Step Guide

As a newcomer to Qunit, I have a query that I'd like to address. I've developed a JavaScript file to incorporate a datepicker and have created a test script using Qunit. My objective is to display the calendar, choose a date, and confirm that th ...

Uploading large files on Vuejs causes the browser to crash

Whenever I try to upload a file using my browser (Chrome), everything goes smoothly for files with a size of 30mb. However, if I attempt to upload a file that is 150mb in size, the browser crashes. The server's maximum upload size has been configured ...

The upcoming feature in Discord.js Commando is the need to have an async function for hasPermission() in order to wait for a database query

Currently, I am developing a discord bot with the help of discord.js and its commando framework. One of the important aspects is storing information in a mongodb database such as server prefixes or roles required for specific commands to execute. The com ...

What is the best way to assign a value to the param tag of an applet using JavaScript variables

This is my external javaScript file named myJs.js function search(){ var hint = document.getElementById("sChoice").value; var item = document.getElementById("sKey").value; document.getElementById("c").value=hint; document.getElementById ...

What is the best way to retrieve the value of a JavaScript variable and display it within an HTML label tag

In my JavaScript code, I'm attempting to retrieve location coordinates using the onchange event and then display those coordinates in a label. I've tried alerting the coordinates successfully, but I'm struggling to update the label using doc ...

The options in the dropdown menu vanish when interacting with a jQuery feature that relies on

Recently, I have found AJAX, JSON, and jQuery to be indispensable tools in my coding endeavors. The application I am working on is a replacement for a flawed one, and it is coming along nicely. Despite making progress with the AJAX method, I have encounte ...

Reconstructing the reporting database within Sitecore 8

Currently running on Sitecore 8.0 rev. 150812 and recently installed WFFM 8 rev. 150625. Experimented with a few WFFM forms and noticed that the data was being stored in MongoDb [FormData collection], yet no data appeared in the Form reports. Only one for ...

Is there a way to provide a dynamic value for the p:remoteCommand ajax call?

My issue involves a p:dataTable that contains p:commandLink elements. I need to initiate an ajax call with parameters when the mouseover event occurs. After some research, it became clear that commandLink cannot trigger an ajax call on mouseover directly - ...

Having trouble with Jest tests after transitioning to TypeScript

After transitioning my project from vanilla JavaScript to TypeScript, I encountered a strange issue with some test cases breaking. Despite everything running smoothly before the switch, certain tests using Vue.js, vue-test-utils, and jest are now failing. ...

Distribute the capabilities of the class

Is there a way to transfer the functionalities of a class into another object? Let's consider this example: class FooBar { private service: MyService; constructor(svc: MyService) { this.service = svc; } public foo(): string { ...

Prevent selection on all elements except for input fields with the type of text

I am facing a challenge where I need to prevent selection on a website page for everything except input[type=text] elements. The answer provided in this accepted response to a similar query almost solves the issue. However, it doesn't stop users from ...

Transform the Angular function into a factory and take advantage of caching

My query differs from others with a similar title. I am attempting to transform a function into a factory in order to share data across controllers, but unlike my other factories, this one is not functioning as expected. I have successfully implemented ot ...

Maintain cookie data between pages to remember form inputs

The scenario: A form is utilized to capture the input value using $thisSearch.val(), store it as a cookie, and then add it to an array. This form is displayed as an overlay triggered from a menu item in the website header, allowing it to be accessed from a ...

Mapping Form Fields (with Formik)

Currently, the Formik/Yup validation setup in my form is working perfectly: export default function AddUserPage() { const [firstName, setFirstName] = useState(""); const [email, setEmail] = useState(""); return ( <div> <Formik ...

Connecting a GridView to a database in MVC 5 using C# while utilizing ajax JavaScript techniques

I am struggling with creating a grid without using Kendo. I am trying to build a dictionary where I have a list of words that I pass to an AJAX JavaScript and display it in a grid on the view. However, I am having trouble figuring out how to make this work ...