Skip to content
Advertisement

Call a function “dynamically” in JS with something like

I’m trying to learn how to dynamically create objects and apply functions to them with JS and HTML. How can I use a <select> dropdown’s text/value to call a function on an object as directly as possible? In the past I’ve used functions in an array, if then statement, or conditional chain but this seems like extra work.

I’m open to suggestions on dynamic object instance creation as well because I’m not sure my method in this example is best practice.

Here is my example:

HTML

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <input id="name" placeholder="name">
        <button id="new">add new object</button>
        <br>
        <input id="property" placeholder="property value">
        <select id="functions">
            <option>apply a function</option>
            <option value="myFunction()">sum</option>
            <option value="myFunction2()">multiply</option>
        </select>
    </body>
    <script src="dynamic-objects.js"></script>
</html>

JS

// Class and its functions
function myClass() {
    this.existingProperty = 5 
}
myClass.prototype.myFunction = function () {
    this.resultProperty = this.newProperty + this.existingProperty
}
myClass.prototype.myFunction2 = function () {
    this.resultProperty = this.newProperty * this.existingProperty
}

// Memory
const locoParentis = []
let nameField = ''
let propField = 0

// Name of object instance of myClass (for example: type dogs into the brower/HTML "name" input)
document.querySelector('#name').addEventListener('change', (e)=>{
    nameField = e.target.value
})
// Add the new objeect instance to the array (for example: click add new object to create an object called dogs with an existingProperty of 5)
document.querySelector('#new').addEventListener('click', ()=>{
    locoParentis[nameField] = new myClass()
    console.log(locoParentis)
})
// Create/set new property in object instance (for example: typing 9 in the property value input sets dogs' newProperty to 9)
document.querySelector('#property').addEventListener('input', (e)=>{
    locoParentis[nameField].newProperty = Number(e.target.value)
    console.log(locoParentis)
})

// Apply prototypical functions on object instance (for example: chosing sum outputs 14 into the console.)
document.querySelector('#functions').addEventListener('change', (e)=>{
    console.log(e.target.value)
    //HOW CAN I CHANGE THIS INTO SOMETHING LIKE locoParentis[nameField].e.target.value() 
    e.target.value === "myFunction()" ? locoParentis[nameField].myFunction() : locoParentis[nameField].myFunction2()
    console.log(locoParentis[nameField].resultProperty)
})

Description: I can create a new object instance of myClass dynamically by typing a name into the name <input> but I would like to do a similar approach with the <select> and the prototypical functions of myClass.

Advertisement

Answer

// Class and its functions
function myClass() {
    this.existingProperty = 5;
}
myClass.prototype.myFunction = function () {
    this.resultProperty = this.newProperty + this.existingProperty;
}
myClass.prototype.myFunction2 = function () {
    this.resultProperty = this.newProperty * this.existingProperty;
}

// Memory
const locoParentis = {};
let nameField;

// Name of object instance of myClass (for example: type dogs into the brower/HTML "name" input)
document.querySelector('#name').addEventListener('change', (e)=>{
    nameField = e.target.value;
})
// Add the new objeect instance to the array (for example: click add new object to create an object called dogs with an existingProperty of 5)
document.querySelector('#new').addEventListener('click', ()=>{
    locoParentis[nameField] = new myClass();
    console.log(locoParentis);
})
// Create/set new property in object instance (for example: typing 9 in the property value input sets dogs' newProperty to 9)
document.querySelector('#property').addEventListener('input', (e)=>{
    locoParentis[nameField].newProperty = Number(e.target.value);
    console.log(locoParentis);
})

document.querySelector('#functions').addEventListener('change', (e)=>{
    // you can check here for undefined 
    locoParentis[nameField][e.target.value]();
    console.log(locoParentis[nameField].resultProperty);
})
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <input id="name" placeholder="name">
        <button id="new">add new object</button>
        <br>
        <input id="property" placeholder="property value">
        <select id="functions">
            <option>apply a function</option>
            <option value="myFunction">sum</option>
            <option value="myFunction2">multiply</option>
        </select>
    </body>
</html>

Try this one.

But there is something to consider. You don’t need to add a seperate `add new object` button. A new instance can be created when you select whether to sum or multiply.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement