Customizing functions in JavaScript with constructor property

What is the best way to implement method overriding in JavaScript that is both effective and cross-browser compatible?


        function Person(firstName, lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        };

        Person.prototype.sayHi = function() {
            return "Hi, my name is " + this.firstName;
        };

        function Employee(firstName, lastName, position) {
            Person.call(this, firstName, lastName);
            this.position = position;
        };

        Employee.prototype = Object.create(Person.prototype);

        Employee.prototype.sayHi = function() {
            return this.constructor.prototype.sayHi() + " I'm a " + this.position;
        }
    

I could also use:


        Employee.prototype.sayHi = function() {
            return Person.prototype.sayHi() + " I'm a " + this.position;
        }
    

but with this solution I'm referring to direct method. Alternatively, I can use:


        Employee.prototype.sayHi = function() {
            return this.__proto__.sayHi() + " I'm a " + this.position;
        }
    

however, this approach may not be supported across all browsers.

EDIT: Assuming Object.create is cross-browser since a shim can be used

Answer №1

Using the constructor property of the prototype to call parent functions is not recommended, as it typically points to the children constructor.

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

While referencing the parent prototype directly may seem like a safer option, there could be errors in the implementation.

If you invoke sayHi without utilizing call or apply, the context of this will be set to Person.prototype instead of the current employee instance.

Employee.prototype.sayHi = function() {
  return Person.prototype.sayHi.call(this) + " I'm a " + this.position;
};

An alternative approach involves storing a reference to the parent prototype in the children prototype.

 Employee.prototype.super = Person.prototoype;

 Employee.prototype.sayHi = function() {
    return this.super.sayHi.call(this) + " I'm a " + this.position;
 };

Another method includes wrapping each function of the children prototype in a dynamic function that sets a reference to the parent function on the object instance, allowing the use of this.parent() for invocation. However, this solution may impact performance and memory usage negatively.

A demonstration of this concept can be found in a JSFiddle example.

Answer №2

No.

Employee prototype is created using the Object.create method on the Person prototype.

Object.create may not be compatible with older browsers, but it can be shimmed.

Employee prototype includes a new method called sayHi which appends its position to the greeting message.

The use of this.constructor within the method is discouraged as it may not reliably refer to the parent object. A better approach would involve explicitly calling the desired function:

return Person.prototype.sayHi.call(this) + " I'm a " + this.position;

If dynamic referencing is required, Object.getPrototypeOf can be used in place of the constructor:

return Object.getPrototypeOf(Employee.prototype).sayHi.call(this) + " I'm a " + this.position;

However, support for Object.getPrototypeOf might be lacking in some older browsers. To ensure cross-browser compatibility and DRY code, consider utilizing the module pattern:

(function(proto, super) {
     proto.sayHi = function() {
         return super.sayHi.call(this) + " I'm a " + this.position;
     };
     …
})(Employee.prototype, Person.prototype);

Alternatively, the revealing prototype pattern can also be employed:

Employee prototype is defined by a self-invoking function that extends the superclass functionalities and adds the sayHi method.

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

Error: Missing semicolon at line 1005 in Vue computed function. Vetur is indicating this issue

As a beginner in vue3, I am venturing into building some side projects. However, I keep encountering an error message stating ';' expected.Vetur(1005) when attempting to utilize the computed function. Strangely enough, sometimes the same syntax w ...

Is it possible to create a MongoDB query that can retrieve a specific number of documents from different types within a single collection?

If I have a collection named "pets" with three different types of animals: cat, dog, and bird What if there are 10 cats, 10 dogs, and 10 birds in the collection (30 documents total)? Can I create a query that retrieves 3 cats, 2 dogs, and 1 bird all at o ...

Retrieve the processed data from a file using node.js

I have successfully read and parsed my file, however I am facing an issue with retrieving the output string. I want to access this string from a variable assigned to it on the client side. Despite using async series to handle callback functions effective ...

TinyMCE generates HTML code with embedded tags

Hey there, I'm currently facing an issue with TinyMCE that I just can't seem to solve. I've browsed through some related posts but haven't found a solution that works for me... For example: When I input something in my back office, ...

Can we include intricate items within a redux store?

As I delve into developing a React application with Redux, I encountered an unexpected scenario. At one point, we inserted a DOM element within the store, causing issues with the Redux extension that freezes when the action is triggered. Despite this compl ...

Issues with dynamically generating buttons using Ajax and Javascript technology

In order to dynamically create buttons based on the contents of a text file during the onload event, I have written a JavaScript function. However, despite being able to read the file and using alert messages to verify the correctness of the variable &apos ...

Unable to transfer data from Laravel's Blade template to a Vue component

Need help passing a value from Laravel to Vue. I'm facing an issue where the props I receive are always showing as undefined in the console.log output. I've double-checked for camel case errors but can't seem to find the root cause of the pr ...

Ways to alert user prior to exiting page without initiating a redirect

I have a feature on my website where users can create and edit posts. I want to notify them before leaving the page in these sections. Here's how I can accomplish that: //Add warning only if user is on a New or Edit page if(window.location.href.index ...

Collect data entered into the input box and store them in an array for the purpose of

I need assistance with a code that involves input boxes for users to enter numerical values, which are then stored in an array. My goal is to add these values together and display the sum using an alert when a button is clicked. However, I am struggling to ...

Split up the author page description with a new line break for better readability on WordPress

I have a unique plugin that transforms the Biographical Info editor into a standard editor interface. However, I am facing an issue where line breaks/new rows created in the backend are not visible on the front end, and I'm unsure of where the problem ...

Utilizing a dictionary within an Angular controller

Currently, I am working on a complex process that involves Angular and MVC controllers interacting with a REST API to retrieve configuration items. The challenge lies in transforming this data into a usable format within the Angular controller for various ...

The writeToDB function is triggered only one time

I've encountered an issue with my node.js code where the writeToDB function is being called, but data is not inserted in the database after the first time. Can someone help me understand why? uploadInfoObject = { ProcessId: pid, Type: "type", ...

Ways to specify the specific option within a select field

Here is my question: <select name="currency" id="currency"> <option value="AUD"&lgt;AUD</option> <option value="BDT"&lgt;BDT</option> <option value="EUR"&lgt;EUR</option> & ...

What is the equivalent of preg_replace in PHP using jquery/javascript replace?

One useful feature of the preg_replace function in PHP is its ability to limit the number of replacements made. This means that you can specify certain occurrences to be replaced while leaving others untouched. For example, you could replace the first occu ...

Adjust the navigation text and logo color as you scroll on the page

I am new to HTML and CSS and I am working on a website with PagePiling.js scrolling feature. I want to change the color of my logo image and navigation text dynamically as I scroll to the next section. Specifically, I only want the part of the logo and tex ...

Adjust the button's hue upon clicking it

The current function is operational. Upon pressing the button, it toggles between displaying "click me" and "click me again". However, I desire the button to appear blue when showing "click me" and red when displaying "click me again". <!DOCTYPE html ...

Tips for correctly mapping a shuffled array in React/Next without triggering a hydration mismatch error

I've been working on a Next.js website and I'm trying to display a randomized list of famous quotes. To achieve this, I'm using lodash to shuffle the array of quotes and then mapping them onto the page. import { useMemo } from 'react&ap ...

Detecting changes in checkbox states

In my current scenario, I have a section of the screen that can be shown or hidden depending on whether a checkbox is checked. The user can change the state of the checkbox manually or programmatically. The challenge lies in detecting this change and upda ...

Optimizing NodeJS for scheduling and sending bulk text messages based on MongoDB data

I am currently developing an application that relies on MongoDB database entries to send text messages through AWS. The information stored in the database includes the message content, phone number, and scheduled time for sending the message. As of now, ...

Can values be manually inserted into session storage for the purpose of local testing?

I typically work on my local eclipse and local IDEs such as Sublime Text, using XAMPP locally for development. Since local code does not involve authentication and other complex aspects, I am considering manually injecting session storage values into my we ...