Passing a particular method of a specific instance as an argument

I am interested in creating a class that allows me to specify "For instance a1 of A, you will call the function computeValue() of a specific instance b1 of B when the value is needed". It's important for me to indicate which method of which instance will be utilized by this particular instance.

So far, I have discovered two potential solutions :

The eval() approach :

class A {

  constructor(funcToCall) {
    this.funcToCall = funcToCall;
  }

  displayValue() {
    console.log(eval(this.funcToCall));
  }
}

class B {

  constructor(value) {
    this.value = value;
  }

  computeValue() {
    return this.value;
  }
}


var b1 = new B(1);
var a1 = new A("b1.computeValue()");
a1.displayValue();// Displays "1", okay

The function.call() approach :

class A {

  constructor(funcToCall, instanceToCallItOn) {
    this.funcToCall = funcToCall;
    this.instanceToCallItOn = instanceToCallItOn;
  }

  displayValue() {
    console.log(this.funcToCall.call(this.instanceToCallItOn));
  }
}

class B {

  constructor(value) {
    this.value = value;
  }

  computeValue() {
    return this.value;
  }
}


var b1 = new B(1);
var a1 = new A(b1.computeValue, b1);
a1.displayValue(); // Displays "1", okay

In my opinion, the eval() solution seems messy while the function.call() appears to be more organized.

Which approach do you think is superior? Are there any alternative and elegant ways to solve this problem?

Answer №1

It is highly recommended to use functions instead of relying on eval(). An alternative approach to simplify the second method is by utilizing .bind(), which eliminates the need to pass the function and instance separately.

class A {
    constructor(funcToExecute) {
        this.funcToExecute = funcToExecute;
    }

    showResult() {
        console.log(this.funcToExecute());
    }
}

// The code for class B remains the same

var b1 = new B(1);
var a1 = new A(b1.calculateValue.bind(b1));
a1.showResult();

If you still opt to pass the instance separately, you can integrate the use of .bind() within the constructor:

class A {
    constructor(funcToExecute, instance) {
        this.funcToExecute = funcToExecute.bind(instance);
    }

    displayFinalOutput() {
        console.log(this.funcToExecute());
    }
}

Answer №2

Ah, the eval technique can be rather messy and unreliable, especially if b1 isn't within the correct scope. While using call is acceptable, there are even better alternatives:

  • One option is to pass both the instance and method name as parameters:

    class A {
      constructor(instance, methodName) {
        this.instance = instance;
        this.methodToCall = methodName;
      }
    
      displayValue() {
        console.log(this.instance[this.methodToCall]());
      }
    }
    var a1 = new A(new B(1), "computeValue");
    
  • Another approach is to pass a function that handles the method call and any additional requirements independently:

    class A {
      constructor(funcToCall) {
        this.funcToCall = funcToCall;
      }
    
      displayValue() {
        console.log(this.funcToCall());
      }
    }
    var b1 = new B(1);
    var a1 = new A(() => b1.computeValue());
    // or:   new A(b1.computeValue.bind(b1))
    // or any other suitable function
    

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

Dynamically insert innerHTML content into table rows using JavaScript in PHP is a fantastic way to customize

Having trouble with innerHTML in this scenario, looking to achieve something along these lines: <table width="100%" border="0" id="table2"> <?php include("connection.php"); $sql=mysql_query("select* from b1"); while($res=mys ...

How can we dynamically navigate to the next line within the Material UI DataGrid component when space is limited?

Currently, I am working with the datagrid component from material ui. I have retrieved some data from a database and am attempting to pass it to the datagrid component. However, I have noticed that certain fields contain long strings which do not fully app ...

I'm encountering some puzzling errors from the Codacy feature in GitHub that are leaving me completely baffled

I'm currently using Codacy in my code repository to assess the quality of my work. Struggling with two errors during commit, unsure how to troubleshoot them. Can anyone offer assistance? Issue: Expected property shorthand. Error occurs in this line ...

implement a user input field within a div using JavaScript

I have created a lightbox in my HTML page with the following structure: <div id="container"> <input type="text" id="user_1" name="user_1" value="user_1"/><br> <input type="text" id="user_2" name="user_2" value="user_2"/>< ...

What is the best way to dynamically select and deselect radio buttons based on a list of values provided by the controller?

I am currently working on implementing an edit functionality. When the user initially selects a list of radio buttons during the create process, I store them in a table as a CSV string. Now, during the edit functionality, I retrieve this list as a CSV stri ...

Refresh the datatable using updated aaData

How do I automatically update the Datatable with new Json data? POST request is used to receive data, which is then sent to the LoadTable function in order to populate the datatable. function initializeTable(){ $("#submitbutton").on( 'click', ...

The Material UI Select Component has the ability to transform a controlled text input into an uncontrolled one

I encountered a warning in the console while trying to update the value of a Select input. The warning message is as follows: index.js:1446 Warning: A component is changing a controlled input of type text to be uncontrolled. Input elements should not swi ...

Exploring the functionality of the $.each jQuery iterator. Can someone clarify the distinctions between these two methods?

Having vertices as an array of google.maps.LatLng objects means that they should return latlng points. The first code snippet works perfectly fine, however, I encounter issues when using the second one. // Iterate over the vertices. for (var index =0; ind ...

JavaScript: Changing the names of all object keys

As a beginner, I am struggling to rename some objects in my key using a map function. Below is my current array: "platforms": [ { "id": 6, "name": "PC (Microsoft Windows)" }, { "id": 11, "na ...

creating a loop to handle AJAX requests for JSON data

My JSON call successfully loads the data.root.offer[0].region data into a div with the class .region. Here is the code snippet: $.getJSON('json/data.json', function(data) { $('.region').html('<p>' + data.root.offer[0] ...

Utilize the Vue-Chartjs plugin registration for a specific chart component only

I am currently working with a chart component in Vue 3 using the composition API. My goal is to incorporate the datalabels plugin into this specific chart only. Upon attempting to register the plugin outside of the chart's data or options, I noticed ...

unselect the button using jQuery

I want to trigger a popover when a variable exceeds a certain value, triggered by clicking a button: $(function () { $('[data-toggle="tooltip"]').tooltip({ trigger: 'manual', placement: 'top', titl ...

Identifying sluggish hardware or unresponsive browsers using JavaScript

My site features numerous CSS animations and transitions that run very slowly on specific browsers and older hardware. I want to avoid user-agent sniffing; is there a way to identify browsers or hardware configurations using JavaScript or a JS library, and ...

Effortless Page Navigation - Initial click may lead to incorrect scrolling position, but the subsequent link functions perfectly

While implementing the Smooth Page Scroll code from CSS Tricks, we encountered an issue where clicking on a navigation link for the first time only scrolls down to a point that is approximately 700px above the intended section. Subsequent clicks work perfe ...

The knockout click event isn't functioning properly for a table generated by ko.computed

My goal is to connect a table to a drop-down menu. Here are the key points of what I'm trying to achieve: The drop-down should list MENUs. Each MENU can have multiple MODULES associated with it, which will be displayed in the table based on the ...

Ways to invoke Java function using Javascript (Client-side)

I have a Java Swing application that handles the User Interface, but requires JavaScript files for hardware testing. The application calls a JavaScript engine to execute functions using the `InvokeFunction()` method. Currently, I am utilizing the LabJack ...

Stop a user from adding duplicate tasks

I have developed a JavaScript code for creating a todo list. Currently, I am working on the phase of adding tasks to the list. The user wants to ensure that if a task is entered once, it cannot be entered again. const taskInput = document.getElementById(&a ...

Angular 2 - synchronizing timer for all users

I have developed a timer that needs to function consistently for all users at the same time. To achieve this, I stored the start_time (timestamp when the timer begins) in my database and implemented the following code snippet to calculate the remaining ti ...

Please type the file name into the provided text box

Is there a way to automatically insert the filename of an uploaded file into an existing text input using either or valums.com/ajax-upload/? (I am working with php) For example, in a textbox: <input name="image" type="text" value="file_name" /> ...

MYSQL table successfully created, however encountering a 500 error when attempting to post data

I've been working with the Node module KNEX for making MYSQL calls, and I'm trying to allow users to add their own custom tables. I have successfully added a database to MYSQL with all the necessary columns, but unfortunately, I keep encountering ...