Ravi
Ravi

Reputation: 159

Replace eval to call a function with in a variable namespace or outside the variable namespace

I am having a variable namespace. From that namespace I need to call a function. I have written a function outside the variable namespace. If I use window[functionName] then that function is calling and executing.

Suppose if I place the function inside the variable namespace, then that function is not getting called. If I use eval then it is working. Is there any replacement of eval to call a function within a variable namespace.window[funcitonName].call(args) only executes if that function is in global.

My requirement is like this:

var xxx = xxx || function($) {

  function onVehicleChange(..., functionName, ....) {
    window[functionName](this, args);
  }

  function maruthiVehicle(args) {

  }
}

Here I am getting function Name dynamically. Suppose my functionName here is maruthiVehicle; I am hard-coding that function here.

window[functionName] now become as window[maruthiVehicle] not calling because my function(maruthiVehicle) is inside the variable namespace(XXX). Suppose if I put my function(maruthiVehicle) outside this variable namespace(xxx) then it works.

So window[functionName] only working here in global scope. I tried to use eval. eval is working fine when I put the function outside or inside the variable namepsace;

I don't want to use eval. I want replacement of this eval.

eval(functionName + "(args)"); Irrespective of my function placement inside the variable or outside the variable namespace my function call should get trigger.

Upvotes: 1

Views: 246

Answers (2)

Ravi
Ravi

Reputation: 159

function testGlobalNetworkChange(xyz, $) {
    console.log("selectoris " + this.id + ',' + "mode is "
                + xyz+ ',' + "jQuery instance is " + $);
}

    var netowrk= network|| (function($) {
    'use strict';
    return {
        onNetworkChange: onNetworkChange,
        testnetworkChange: testnetworkChange
    };

    function testnetworkChange(mode, $) {
        console.log("AttributeSelector is " + this.id + ','
                    + "mode is "+ mode + ',' + "jQuery instance is " + $);
    }

    function solveFunction(functionName, context) {
        var namespaces = functionName.split(".");
        var func = namespaces.pop();
        for (var i = 0; i < namespaces.length; i++) {
            context = context[namespaces[i]];
        }
        return context[func];
    }

    function OnNetworkChange(selector, functionName, xyz, $) {
        var func = solveFunction(functionName, window);
        $('#' + Selector).change(function(e) {
            func.apply(this, [xyz, $]);
        });
    }
})(jQuery);

// Invoking your function to test. network.onNetWorkChange(parameters);

Upvotes: 0

jl_
jl_

Reputation: 5539

I believe you could structure the code like below:

/* 
 * Global varibale - a namespace / place holder to keep the entities related to the application
 * This goes into the global variable - `window`
 */
vehicleNamespace = window.vehicleNamespace || {};

/* 
 *  Add functionality into that object
 */
vehicleNamespace = (function() {

  // Create a `local` function.
  var maruthiVehicle = function() {
    console.log("This is Maruthi");
  };
  
  // Return the object(s) that should be public in `vehicleNamespace`
  return {
    maruthiVehicle: maruthiVehicle
  }
})();

// call the function
window.onload = function() {
  vehicleNamespace.maruthiVehicle();
};

In order to call the function dynamically, you could use call or bind based on the requirements.

See the snippet below on its usage:

/* 
 * Global varibale - a namespace / place holder to keep the entities related to the application
 * This goes into the global variable - `window`
 */
vehicleNamespace = window.vehicleNamespace || {};

/* 
 *  Add functionality into that object
 */
vehicleNamespace = (function() {

  var maruthiVehicle = function(input) {
    console.log(input);
  };

  var onVehicleChange = function(functionName, output) {
    // Note: You could also add more validations here to check if it is a `function`
    if (typeof functionName == 'function') {
      functionName.call(this, output);
    }
  }

  // Return the object(s) that should be public in `vehicleNamespace`
  return {
    maruthiVehicle: maruthiVehicle,
    onVehicleChange: onVehicleChange
  }
})();

// call the function
window.onload = function() {
  vehicleNamespace.maruthiVehicle("This is Maruthi");
  vehicleNamespace.onVehicleChange(vehicleNamespace.maruthiVehicle, "Selected Maruthi");
};

Upvotes: 1

Related Questions