Замените eval для вызова функции на в пространстве имен переменных или вне пространства имен переменных

#javascript #eval

#javascript #eval

Вопрос:

У меня есть переменная namespace . Из этого пространства имен мне нужно вызвать функцию. Я написал функцию вне переменной namespace . Если я использую window[functionName] , то эта функция вызывается и выполняется.

Предположим, если я помещу функцию внутри пространства имен переменных, то эта функция не вызывается. Если я использую eval , то это работает. Существует ли какая-либо замена eval для вызова функции внутри переменной namespace.window[funcitonName].call(args) , которая выполняется только в том случае, если эта функция является глобальной.

Мое требование такое:

 var xxx = xxx || function($) {

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

  function maruthiVehicle(args) {

  }
}  

Здесь я получаю имя функции динамически. Предположим, что мой functionName here maruthiVehicle ; Я жестко кодирую эту функцию здесь.

window[functionName] теперь станьте как window[maruthiVehicle] не вызывающий, потому что my function(maruthiVehicle) находится внутри переменной namespace(XXX) . Предположим, если я помещу свою function(maruthiVehicle) вне этой переменной namespace(xxx) , тогда это сработает.

Так window[functionName] что здесь работает только global область видимости. Я пытался использовать eval . eval работает нормально, когда я помещаю функцию вне или внутри переменной namepsace ;

Я не хочу использовать eval . Я хочу заменить это eval .

eval(functionName "(args)"); Независимо от размещения моей функции внутри переменной или вне пространства имен переменных, мой вызов функции должен получить триггер.

Ответ №1:

Я полагаю, вы могли бы структурировать код, как показано ниже:

 /* 
 * 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();
};  

Для вызова функции dynamically вы можете использовать call или bind на основе требований.

Смотрите Фрагмент ниже о его использовании:

 /* 
 * 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");
};  

Комментарии:

1. Ошибка типа: functionName.call не является функцией. это не работает

2. Проверьте type параметр using typeof(functionName) и убедитесь, что это a function ; Я внес изменения в приведенный выше код.

3. функция resolveFunction(functionName, context) { var namespaces = functionName.split(«.»); var func = namespaces.pop(); for (var i = 0; i < пространства имен. длина; i ) { контекст = контекст[пространства имен[i]]; } возвращает контекст[функция]; }

4. var func = resolveFunction(functionName, window); $(‘#’ xxxxx).change(функция(e) { func.apply(this, [параметр, $]); });

Ответ №2:

 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);
  

// Вызов вашей функции для тестирования.
network.onNetWorkChange(параметры);

Комментарии:

1. Вы можете удалить свои комментарии и отредактировать свой ответ, а вместо этого добавить описания к своим комментариям, чтобы сделать его более понятным. И отметьте свой ответ как ответ.

2. @Sneak добавлен согласно вашему предложению.

3. @Sneak также удалил мои комментарии