Enhance the functionality of function() by incorporating another function from a different external file

I find myself in a situation where I need to create a web client interface that can interact with different types of hardware. The interface has a core component, and additional features depending on the hardware connected (specifically, the login() process varies per device).

As a C++ developer stepping into the realm of JavaScript extensions for this project, I must admit, I feel quite overwhelmed.

Here is the scenario I crafted for testing purposes:

Source1.js (considered as the universal base interface across all hardware):

function Login() {
    this.type = 'login';
    m_username = 'admin';
    m_password = 'admin';
}

function Constructor() {
    var mClass = new Login();
    this.clicked = function() {
        mClass.clicked();
    }

    this.getLogin = function() {
        return mClass;
    }
}

g_constructor = new Constructor();

Source2.js (contains the custom implementation of Login().clicked()):

function Login() {
    this.clicked = function() {
        document.getElementById("TextHere").innerHTML = m_username + ":" + m_password;
    }
}

The HTML File used for testing:

<html lang="en">
    <head>
        <title>JavaScript Test</title>
        <meta charset="utf-8" />
        <script src="source1.js"> </script>
        <script src="source2.js"> </script>
    </head>
    <body>
        <button onClick="g_constructor.clicked()">Test</button>
        <p>&nbsp;</p>
        <div id="TextHere">Text</div>
    </body>
</html>

In my usual domain of C++, I typically rely on virtual base classes for such implementations. However, when it comes to JavaScript, I am at a loss. Can someone point me in the right direction on how to achieve a similar structure? Specifically, ensuring that every object of Login() type possesses the clicked() function as defined in Source2.js.

Answer №1

In the realm of JavaScript, things operate slightly differently. Objects are crafted with a prototype object. By defining methods on the prototype object, you can then override them with an actual implementation.

When defining methods on the prototype, it is essential not to define them as a property of this.

// This snippet could be part of source file 1
function Login() {
    this.type = 'login';
    this.m_username = 'admin';
    this.m_password = 'admin';
}

function Constructor() {}

Constructor.prototype = new Login();
Constructor.prototype.clicked = function () {
    alert('You should implement the "clicked" method');
};

var g_constructor = new Constructor();

// This snippet could be part of source file 2 

Constructor.prototype.clicked = function () {
    document.getElementById("TextHere").innerHTML = this.m_username + ":" + this.m_password;
}
<button onClick="g_constructor.clicked()">Test</button>
<p>&nbsp;</p>
<div id="TextHere">Text</div>

You may have observed that m_username is designated as a property of this, otherwise it won't be accessible later on: in JavaScript, a plain variable (when appropriately defined with the var keyword) is only reachable within the function's scope where it was defined.

With the more modern ES6 syntax (utilizing class and extends), the code could appear like this:

// This snippet could be part of source file 1
class Login {
    constructor() {
        this.type = 'login';
        this.m_username = 'admin';
        this.m_password = 'admin';
    }
}

class Constructor extends Login {
    clicked () {
        alert('You should implement the "clicked" method');
    }
}

var g_constructor = new Constructor();

// This snippet could be part of source file 2 

Constructor.prototype.clicked = function () {
    document.getElementById("TextHere").innerHTML = this.m_username + ":" + this.m_password;
}
<button onClick="g_constructor.clicked()">Test</button>
<p>&nbsp;</p>
<div id="TextHere">Text</div>

Note: The getLogin method is not actually necessary, as the g_constructor object already encompasses all the attributes of Login.

Answer №2

When comparing JavaScript to C++, it is important to note that JavaScript does not utilize the virtual function concept. Instead, you can achieve similar functionality by using composition. Methods can be added to an object in the following manner:

function A() {
 this.virtualFunction();
  }

A.prototype.virtualFunction = function() {
     alert('A');
   };
 //-------------------------------------

function B() {
      A.call(this);
 }

 B.prototype = Object.create(A.prototype);
 B.prototype.constructor = B;
 B.prototype.virtualFunction = function() {
      alert('B');
  };

  var b = new B();

It should be noted that this example was sourced from another website.

Answer №3

Initially, it may not be the best approach to split JavaScript functionality across multiple files. However, if you do wish to do so, one way is to modify the prototype of an existing class like Login and verify its existence before calling a method:

source1.js:

function Login() {
    this.type = "login";
    this._username = "admin";
    this._password = "admin";
}

function Constructor() {
    var mClass = new Login();

    this.clicked = function() {
        if (Object.getPrototypeOf(mClass).hasOwnProperty("clicked"))
            mClass.clicked();
        else
            console.log("Unable to click :(");
    }

    this.getLogin = function() {
        return mClass;
    }
}

g_constructor = new Constructor();

source2.js:

Login.prototype.clicked = function() {
    document.getElementById("TextHere").innerHTML = this._username + ":" + this._password;
}

If you prefer not to check for the method's existence, you can simply add an empty function in your Login.clicked:

var virtualMethod = function() { console.log("Implementation missing!"); }

function Login() {
    this.type = "login";
    this._username = "admin";
    this._password = "admin";

    this.clicked = virtualMethod;
}

Then you can update it in the second file.

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

connecting with Google Analytics

We are looking to incorporate Google Analytics into a sizable .NET website. The website utilizes multiple master pages (4 or 5), so the plan was to insert the necessary JavaScript code into each master page. <script type="text/javascript">//<![CD ...

Engaging in payment processing

Currently facing a significant dilemma. I am utilizing Stripe as my payment gateway, which functions in a two-step process: Collect billing information to generate a token Charge the client using the generated token The issue arises because the token ca ...

In Laravel, Inertia.js will automatically close a modal if there are no validation errors present

Here is the method I am currently using: methods: { submit() { this.$inertia.post('/projects', this.form); this.openModal = false; }, }, Unfortunately, this method closes the modal even if there are validation erro ...

Having difficulty in closing Sticky Notes with JavaScript

Sticky Notes My fiddle code showcases a functionality where clicking on a comment will make a sticky note appear. However, there seems to be an issue with the Close Button click event not being fired when clicked on the right-hand side of the note. I have ...

JavaScript multiline variable declaration

In the context of a multi-lined variable in AJAX Chat, I am attempting to add an image before other elements are set. However, the issue I am encountering is that the image and text are always displayed on separate lines. It seems to be more of an issue wi ...

Indeed, verifying parent.parent access

Currently, I am utilizing the yup module to validate my form. My objective is to access the parent in order to test the value. Below is my schema: enabled: yup.boolean(), contactDetail: yup.object().shape({ phoneNumber1: yup.string().nullable(), pho ...

React-Redux Error: The function this.props.AppendCharacter is not defined

I have been looking for a solution to my issue but couldn't find anything that matches it. I am working on creating a calculator app using React & Redux, and whenever I click on one of the number buttons, I receive an error message saying "this.props. ...

configure dynamic content within the slider element

Currently, I am experimenting with two jQuery plugins (awkward/Coda Slider 3) to implement a sliding effect for DIV content. Everything seems to be working smoothly until I attempt to set dynamic content (using JavaScript) after creating the plugin object. ...

Struggling to send API POST request using Next.js

I'm relatively new to backend development, as well as Next.js and TypeScript. I'm currently attempting to make a POST request to an API that will receive a formData object and use it to create a new listing. My approach involves utilizing Next.js ...

What is the best way to access the methods in the "parent" class?

I am facing a situation where I have an object with fieldsCreators that hold creator methods for each field. The dilemma is how to call the creator method inside fieldsCreators as shown below: var obj={ creator:function(ch) { .... .. ...

How can I achieve the quickest image loading speed with JavaScript?

If I have a large ecommerce website with 15,000 image elements that need to be added to the HTML, what is the best approach using JavaScript to optimize efficiency and enhance user experience? ...

Transform basic text into nested JSON structure with JavaScript

There is a plain string in my possession which contains various conditions. const optionString = '{2109} AND ({2370} OR {1701} OR {2702}) AND {1234} AND ({2245} OR {2339})'; The goal is to transform this string into an object structured as foll ...

The hamburger menu for mobile devices is not functioning properly on the website's mobile version, however it operates correctly when the screen is resized

Currently, I am facing an issue with the hamburger menu not responding on my mobile device. Oddly enough, it does work when I resize my browser window to mimic a mobile size. There seems to be a glitch happening, but I'm struggling to pinpoint the exa ...

How can I insert an array of string elements into a template element's value attribute in Angular 2?

Inside my Angular 2 component class, I have an array named myArray: @Component({ templateUrl: 'my.component.html' }) export class MyComponent { private myArray: Array<string>; ... } The corresponding HTML file my.component.ht ...

Is it possible for WebSockets to serve as a substitute for AJAX for handling Database requests?

I have recently made the switch on my website from using the EventSource Polling constructor to the WebSocket standard in Node.js. Originally, all backend work on my site was done with PHP, but I am now trying to transition as much as possible to WebSocket ...

The header row in HTML tables sometimes vanishes unexpectedly after sorting the table

Upon filtering the table, I noticed that the header disappears sporadically. The issue is that the table header row should remain in place regardless of whether or not the characters used for filtering are present in the table rows. In Example 1: When fil ...

My extension seems to be missing the content script I uploaded

I am currently developing an extension for Google Chrome. My goal is to create a content script that can retrieve meta tags from the tab when the popup is clicked. In my manifest, I have included the following permissions: "content_scripts": [{ "js" ...

Guide on creating Jasmine tests for $resource in AngularJS

Trying to get started with defining tests for my angular app, but feeling a bit lost as it's my first time working with testing. I'm specifically interested in setting up Tests with Jasmine for REST Services within my application. My main questi ...

Encountering a problem when using the routingService to navigate inside a JavaScript function

Within my Angular component, I have a method called onCellPrepared. In this method, I am using jQuery to attach a span tag. I want to be able to trigger an Angular service to navigate to another page when the span tag is clicked. How can I successful ...

Troubleshooting issue with parsing MySQL data in HTML table using Node.js

Seeking Assistance! I am currently in the process of developing a node file that displays data from MySQL on an HTML page with a search bar. My issue is that sometimes when I run the code, enter something into the search bar and hit the button, it works s ...