questions - javascript programs




एक स्ट्रिंग के रूप में मेरा नाम होने पर जावास्क्रिप्ट फ़ंक्शन निष्पादित कैसे करें (20)

आप eval("functionname as string") भीतर जावास्क्रिप्ट फ़ंक्शन को कॉल कर सकते हैं। नीचे की तरह: (eval शुद्ध जावास्क्रिप्ट समारोह है)

function testfunc(){
    return "hello world";
}

$( document ).ready(function() {

     $("div").html(eval("testfunc"));
});

कार्य उदाहरण: https://jsfiddle.net/suatatan/24ms0fna/4/

मेरे पास जावास्क्रिप्ट में एक स्ट्रिंग के रूप में फ़ंक्शन का नाम है। मैं इसे फ़ंक्शन पॉइंटर में कैसे परिवर्तित करूं ताकि मैं इसे बाद में कॉल कर सकूं?

परिस्थितियों के आधार पर, मुझे विधि में विभिन्न तर्कों को पारित करने की आवश्यकता हो सकती है।

कुछ फ़ंक्शंस namespace.namespace.function(args[...]) ले सकते हैं namespace.namespace.function(args[...])


आपको window[<method name>] द्वारा अपनी स्ट्रिंग को पॉइंटर में बदलने की आवश्यकता है। उदाहरण:

var function_name = "string";
function_name = window[function_name];

और अब आप इसे एक सूचक की तरह उपयोग कर सकते हैं।


इस अन्य प्रश्न का उत्तर आपको यह कैसे दिखाता है: पाइथन के स्थानीय () के बराबर जावास्क्रिप्ट?

असल में, आप कह सकते हैं

window["foo"](arg1, arg2);

या जैसा कि कई अन्य ने सुझाव दिया है, आप केवल eval का उपयोग कर सकते हैं:

eval(fname)(arg1, arg2);

हालांकि यह बेहद असुरक्षित है जब तक कि आप पूरी तरह से सुनिश्चित नहीं हैं कि आप क्या कर रहे हैं।


ईएस 6 के साथ आप वर्ग विधियों को नाम से एक्सेस कर सकते हैं:

class X {
  method1(){
    console.log("1");
  }
  method2(){
    this['method1']();
    console.log("2");
  }
}
let x  = new X();
x['method2']();

आउटपुट होगा:

1
2

जब तक आप बिल्कुल, सकारात्मक रूप से कोई अन्य विकल्प नहीं है , तब तक eval का उपयोग न करें।

जैसा कि उल्लेख किया गया है, ऐसा कुछ करने का यह करने का सबसे अच्छा तरीका होगा:

window["functionName"](arguments);

हालांकि, नामस्थान कार्य के साथ काम नहीं करेगा:

window["My.Namespace.functionName"](arguments); // fail

इस तरह आप ऐसा करेंगे:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

इसे आसान बनाने और कुछ लचीलापन प्रदान करने के लिए, यहां एक सुविधा कार्य है:

function executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

आप इसे इस तरह कहते हैं:

executeFunctionByName("My.Namespace.functionName", window, arguments);

ध्यान दें, आप जो भी संदर्भ चाहते हैं उसे पारित कर सकते हैं, इसलिए यह उपर्युक्त जैसा ही होगा:

executeFunctionByName("Namespace.functionName", My, arguments);

जेसन और एलेक्स की पोस्ट पर एक और जानकारी। मुझे संदर्भ में डिफ़ॉल्ट मान जोड़ने में मदद मिली। बस context = context == undefined? window:context; context = context == undefined? window:context; समारोह की शुरुआत में। आप जो भी अपना पसंदीदा संदर्भ है, उस window को बदल सकते हैं, और फिर जब भी आप इसे अपने डिफ़ॉल्ट संदर्भ में कॉल करते हैं तो आपको उसी वैरिएबल में पास करने की आवश्यकता नहीं होगी।


जेसन बंटिंग के जवाब में जोड़ने के लिए, यदि आप नोडजेस या कुछ (और यह डोम जेएस में भी काम करता है) का उपयोग कर रहे हैं, तो आप window बजाए इसका इस्तेमाल कर सकते window (और याद रखें: eval बुरा है :

this['fun'+'ctionName']();

तत्व का उपयोग करने के लिए इसका सबसे आसान तरीका है

window.ClientSideValidations.forms.location_form

जैसा ही है

window.ClientSideValidations.forms['location_form']

दो चीज़ें:

  • eval से बचें, यह बहुत खतरनाक और धीमी है

  • दूसरी बात यह कोई फर्क नहीं पड़ता कि आपका कार्य कहां मौजूद है, "वैश्विक" -यता अप्रासंगिक है। xyfoo() xy['foo']() या x['y']['foo']() या यहां तक ​​कि window['x']['y']['foo']() । आप इस तरह अनिश्चित काल तक श्रृंखला कर सकते हैं।


बस सोचा कि मैं जेसन बंटिंग के बहुत उपयोगी काम का थोड़ा बदल गया संस्करण पोस्ट करूंगा।

सबसे पहले, मैंने स्लाइस () को दूसरा पैरामीटर आपूर्ति करके पहला कथन सरल बनाया है। मूल संस्करण IE को छोड़कर सभी ब्राउज़रों में ठीक काम कर रहा था।

दूसरा, मैंने इसे रिटर्न स्टेटमेंट में संदर्भ के साथ बदल दिया है; अन्यथा, जब लक्ष्य कार्य निष्पादित किया जा रहा था, तो यह हमेशा विंडो पर इंगित करता था।

function executeFunctionByName(functionName, context /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for (var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    return context[func].apply(context, args);
}

बुनियादी देखें:

var namefunction = 'jspure'; // String

function jspure(msg1 = '', msg2 = '') { 
  console.log(msg1+(msg2!=''?'/'+msg2:''));
} // multiple argument

// Results ur test
window[namefunction]('hello','hello again'); // something...
eval[namefunction] = 'hello'; // use string or something, but its eval just one argument and not exist multiple

अन्य प्रकार के फ़ंक्शन मौजूद हैं कक्षा है और उदाहरण nils petersohn उदाहरण देखें


मुझे लगता है कि ऐसा करने का एक शानदार तरीका हैश ऑब्जेक्ट में अपने कार्यों को परिभाषित करना। फिर आप स्ट्रिंग का उपयोग कर हैश से उन कार्यों का संदर्भ ले सकते हैं। जैसे

var customObject = {
  customFunction: function(param){...}
};

फिर आप कॉल कर सकते हैं:

customObject['customFunction'](param);

जहां कस्टम फ़ंक्शन एक स्ट्रिंग होगा जो आपकी ऑब्जेक्ट में परिभाषित फ़ंक्शन से मेल खाती है।


मैं एक और चाल का उल्लेख करने का विरोध नहीं कर सकता, जो आपके पास अज्ञात संख्या में तर्क है जो फ़ंक्शन नाम वाले स्ट्रिंग के हिस्से के रूप में भी पारित किया जा रहा है । उदाहरण के लिए:

var annoyingstring = 'call_my_func(123, true, "blah")';

यदि आपका जावास्क्रिप्ट एक HTML पृष्ठ पर चल रहा है, तो आपको केवल एक अदृश्य लिंक चाहिए; आप onclick विशेषता में एक स्ट्रिंग पास कर सकते हैं, और click विधि को कॉल कर click

<a href="#" id="link_secret"><!-- invisible --></a>

$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();

या रनटाइम पर <a> तत्व बनाएं।


यदि आप window["functionName"] साथ वैश्विक फ़ंक्शन के बजाय किसी ऑब्जेक्ट का फ़ंक्शन कॉल करना चाहते हैं। आप इसे पसंद कर सकते हैं;

var myObject=new Object();
myObject["functionName"](arguments);

उदाहरण:

var now=new Date();
now["getFullYear"]()

यहां कई executeByName फ़ंक्शन हैं जो ठीक काम करते हैं, जब तक कि नाम में स्क्वायर ब्रैकेट नहीं होते - समस्या मैं भाग गया - क्योंकि मेरे पास गतिशील रूप से जेनरेट किए गए नाम हैं। तो उपरोक्त कार्यों जैसे नामों पर असफल हो जाएगा

app.widget['872LfCHc']['toggleFolders']

एक उपाय के रूप में, मैंने इसे ध्यान में रखने के लिए भी काम किया है, शायद कोई इसे उपयोगी पाएगा:

कॉफीस्क्रिप्ट से उत्पन्न:

var executeByName = function(name, context) {
  var args, func, i, j, k, len, len1, n, normalizedName, ns;
  if (context == null) {
    context = window;
  }
  args = Array.prototype.slice.call(arguments, 2);
  normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.');
  ns = normalizedName.split(".");
  func = context;
  for (i = j = 0, len = ns.length; j < len; i = ++j) {
    n = ns[i];
    func = func[n];
  }
  ns.pop();
  for (i = k = 0, len1 = ns.length; k < len1; i = ++k) {
    n = ns[i];
    context = context[n];
  }
  if (typeof func !== 'function') {
    throw new TypeError('Cannot execute function ' + name);
  }
  return func.apply(context, args);
}

बेहतर पठनीयता के लिए कॉफीस्क्रिप्ट संस्करण भी जांचें:

executeByName = (name, context = window) ->
    args = Array.prototype.slice.call(arguments, 2)
    normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.')
    ns = normalizedName.split "."
    func = context
    for n, i in ns
        func = func[n]

    ns.pop()
    for n, i in ns
        context = context[n];
    if typeof func != 'function'
        throw new TypeError 'Cannot execute function ' + name
    func.apply(context, args)


सेटटाइमआउट का कोई उल्लेख देखने के लिए आश्चर्यचकित।

तर्क के बिना एक समारोह चलाने के लिए:

var functionWithoutArguments = function(){
    console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);

तर्क के साथ समारोह चलाने के लिए:

var functionWithArguments = function(arg1, arg2) {
    console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");

गहराई से नामित फ़ंक्शन चलाने के लिए:

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}
setTimeout("_very._deeply._defined._function(40,50)", 0);

eval('function()') का उपयोग किए बिना आप new Function(strName) का उपयोग करके एक नया फ़ंक्शन बना सकते हैं। नीचे कोड को एफएफ, क्रोम, आईई का उपयोग करके परीक्षण किया गया था।

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

  let t0 = () => { alert('red0') }
  var t1 = () =>{ alert('red1') }
  var t2 = () =>{ alert('red2') }
  var t3 = () =>{ alert('red3') }
  var t4 = () =>{ alert('red4') }
  var t5 = () =>{ alert('red5') }
  var t6 = () =>{ alert('red6') }

  function getSelection(type) {
    var evalSelection = {
      'title0': t0,
      'title1': t1,
      'title2': t2,
      'title3': t3,
      'title4': t4,
      'title5': t5,
      'title6': t6,
      'default': function() {
        return 'Default';
      }
    };
    return (evalSelection[type] || evalSelection['default'])();
  }
  getSelection('title1');

एक और ओओपी समाधान ...


use this

function executeFunctionByName(functionName, context /*, args */) {
      var args = [].slice.call(arguments).splice(2);
      var namespaces = functionName.split(".");
      var func = namespaces.pop();
      for(var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
      }
      return context[func].apply(context, args);
    }







javascript