जब मैं इसका नाम एक स्ट्रिंग के रूप में एक जावास्क्रिप्ट समारोह निष्पादित करने के लिए कैसे


1050

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

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

कुछ कार्यों का रूप ले सकता है namespace.namespace.function(args[...])

जवाबों:


1438

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

4
आप जानते हैं कि आपको पूरे "फंक" निर्माण की आवश्यकता नहीं है? "
संदर्भ.कप्ली

16
ज़रूर, मुझे पता है कि - लेकिन जिस तरह से मैंने फ़ंक्शन लिखा है, उसे पढ़ने वालों के लिए कुछ स्पष्टता प्रदान करता है जो पूरी तरह से नहीं हो सकता है कि क्या हो रहा है। मैंने इस फंक्शन को पढ़ते हुए लोगों को महसूस किया कि इसे कुछ मदद की ज़रूरत हो सकती है। मैं एक विकल्प प्रदान करूंगा, क्योंकि आपने पूछा था ...
जेसन बंटिंग

108
स्क्रैच कि - कोड पर्याप्त स्पष्ट है और जो जानते हैं, जानते हैं। यदि आप मेरे जैसे हैं, और यह जानते हैं कि आप क्या कर रहे हैं, तो आप इस कोड में अपने आप ही इस तरह के बदलाव कर सकते हैं। स्टैक ओवरफ्लो दूसरों को शिक्षित करने के लिए है, और मुझे लगता है कि नौसिखियों को समझने के लिए मेरा कोड आसान है। हालांकि धन्यवाद!
जेसन बंटिंग

4
क्या ऐसी स्थिति है जब खिड़की ["funcName"] अपरिभाषित वापस आ जाएगी? यही वह समस्या है जो इस समय मेरे पास है। कॉलिंग कोड और फ़ंक्शन को दो अलग-अलग js फ़ाइलों में परिभाषित किया गया है। मैंने उन्हें एक ही फाइल में जोड़ने की कोशिश की लेकिन इससे कोई फर्क नहीं पड़ा।
कोडमेक

5
मुझे लगता है कि यहां एक समस्या है। जब आप कॉल करेंगे My.Namespace.functionName(), thisतो My.Namespaceऑब्जेक्ट को संदर्भित करेगा । लेकिन जब आप कॉल करते हैं executeFunctionByName("My.Namespace.functionName", window), thisतो उसी चीज़ को संदर्भित करने का कोई तरीका नहीं होता है। शायद यह गुंजाइश के रूप में अंतिम नाम स्थान का उपयोग करना चाहिए, या windowयदि कोई नामस्थान नहीं हैं। या आप उपयोगकर्ता को तर्क के रूप में गुंजाइश निर्दिष्ट करने की अनुमति दे सकते हैं।
जेडब्ल्यू।

100

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

पहले, मैंने स्लाइस () के लिए एक दूसरे पैरामीटर की आपूर्ति करके पहले कथन को सरल किया है । मूल संस्करण 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);
}

यह देखने के लिए कोई जांच नहीं है कि क्या "फ़ंक्शननेम" वास्तव में मौजूद है?
Crashalot

मुझे लगता है कि मैक का जवाब रेखांकित है। मैं एक विशेषज्ञ नहीं हूं, लेकिन यह अच्छी तरह से सोचा और मजबूत लगता है।
मार्टिन हैनसेन लेनॉक्स

65

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

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

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

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

eval(fname)(arg1, arg2);

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


6
पहला रूप बहुत बेहतर है
15

19
केवल अंतिम उपाय के रूप में eval का उपयोग करें, जब बाकी सब विफल हो जाए।
जेसन बंटिंग

1
यह है ... लेकिन यह इस तरह के कार्यों के साथ काम करेगा: xyz (args)?
कीरोन

@keiron: हाँ। मेरा जवाब नीचे देखें
annakata 16

55

क्या आप ऐसा नहीं कर सकते:

var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();

आप इस पद्धति का उपयोग करके किसी अन्य जावास्क्रिप्ट को भी निष्पादित कर सकते हैं।


3
काम भी जब तर्क के साथ पारित कर रहे हैं
adeel41

समारोह वापसी के बारे में क्या?
पीटर डेनेव

12
वह किस तरह से अलग है eval("My.Namespace.functionName()");?
developerbmw

@PeterDenev सिर्फ पहली लाइन को बदलकरvar codeToExecute = "return My.Namespace.functionName()";
developerbmw

2
@developerbmw, यहाँ उत्तर है stackoverflow.com/questions/4599857/…
तेजस्वी हेगड़े

47

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

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

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

customObject['customFunction'](param);

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


@ibsenv, इस प्रतिक्रिया को सर्वश्रेष्ठ के रूप में पहचानने में आपकी सहायता के लिए धन्यवाद। मैंने फ़ंक्शन ऑब्जेक्ट्स की एक सरणी बनाई और बदले में deferred.promises की एक सरणी बनाने के लिए उपयोग किया। मैंने कुछ नमूना कोड नीचे दिए हैं। (मैं एक नया उत्तर नहीं बनाना चाहता था और रूबेन की प्रतिक्रिया को उधार लेना चाहता था ।)
user216661

फ़ंक्शन getMyData (arrayOfObjectsWithIds) {var functionArray = arrayOfObjectsWithIds.map (फ़ंक्शन (मान) {return {myGetDataFunction: MyService.getMyData (value.id)};} var वादों = functionArray.map (फ़ंक्शन) q.defer (); getDataFunction.myGetDataFunction.success (फ़ंक्शन (डेटा) {deferred.resolve (डेटा)})। त्रुटि (फ़ंक्शन (त्रुटि) {deferred.reject ();}); deferred.promise;}); $ q.all (वादे) .then (फ़ंक्शन (dataArray) {// do stuff})};
user216661

यह उत्कृष्ट काम करता है मैं केवल अंडरस्कोर / लॉश को यह सत्यापित करने के लिए जोड़ता हूं कि क्या यह एक फ़ंक्शन है। और फिर चलाएं
elporfirio

34

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

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

उत्पादन होगा:

1
2

1
सर्वश्रेष्ठ जावास्क्रिप्ट शुद्ध ... भगवान .. काम नहीं कर रहा है और इसके ठीक वर्ग हटा दें। धन्यवाद!
किंगराइडर

1
यह वह चीज है जिसकी मुझे लंबे समय से तलाश थी। धन्यवाद!
पलाड़ीएन

ES2015 का यहां कोई लेना-देना नहीं है। आप शुद्ध वस्तुओं या प्रोटोटाइप डेलिगेशन के माध्यम से उसी लक्ष्य को प्राप्त कर सकते हैं Object.create()। const myObj = {method1 () {कंसोल.लॉग ('1')}, method2 () {कंसोल.लॉग ('2')}} myObj ['method1'] (); // 1 myObj ['मेथड 2'] (); // 2
स्मिनटोली

1
ये सोना है !!! मुझे आश्चर्य है कि मैंने ऐसा पहले कभी नहीं सोचा था। नाइस !!!
thxmike

मुझे भी लगता है कि यह हमारा लक्ष्य हासिल करने का सबसे साफ तरीका है।
क्रिस जंग

24

दो चीज़ें:

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

  • दूसरी बात यह नहीं है कि आपका कार्य कहाँ मौजूद है, "वैश्विक" -समान अप्रासंगिक है। x.y.foo()के माध्यम x.y['foo']()से x['y']['foo']()या यहां तक ​​कि सक्षम किया जा सकता है window['x']['y']['foo']()। आप इस तरह अनिश्चित काल के लिए चेन कर सकते हैं।


1
लेकिन आप विंडो नहीं कर सकते ['xyz'] () xyz () को कॉल करने के लिए
nicf

17

सभी उत्तर मानते हैं कि कार्यों को वैश्विक दायरे (खिड़की) के माध्यम से पहुँचा जा सकता है। हालांकि, ओपी ने यह धारणा नहीं बनाई।

यदि फ़ंक्शन स्थानीय दायरे (उर्फ क्लोजर) में रहते हैं और किसी अन्य स्थानीय वस्तु, खराब भाग्य से संदर्भित नहीं होते हैं: तो आपको eval()AFAIK का उपयोग करना होगा , जावास्क्रिप्ट में स्थानीय फ़ंक्शन को गतिशील रूप से कॉल करना देखें


2
यार (या dudette), बाहर इशारा करने के लिए बहुत बहुत धन्यवाद! मुझे लगा कि मैं एक सेकंड के लिए पागल हो रहा हूं।
फनकट्र्न

13

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

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

और अब आप इसे पॉइंटर की तरह इस्तेमाल कर सकते हैं।


यह ज्यादा सुरक्षित तरीका लगता है।
जेम्स पॉल्स

12

यहाँ जेसन बंटिंग / एलेक्स नाज़रोव के उत्कृष्ट उत्तरों में मेरा योगदान है, जहाँ मैं क्रैशहॉल द्वारा अनुरोधित त्रुटि जाँच शामिल हूं।

इसे (प्रतिवेदित) प्रस्तावना दिया गया:

a = function( args ) {
    console.log( 'global func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
ns = {};
ns.a = function( args ) {
    console.log( 'namespace func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nsa';
n_s_a = [ 'Snowden' ];
noSuchAgency = function(){};

तब निम्न कार्य:

function executeFunctionByName( functionName, context /*, args */ ) {
    var args, namespaces, func;

    if( typeof functionName === 'undefined' ) { throw 'function name not specified'; }

    if( typeof eval( functionName ) !== 'function' ) { throw functionName + ' is not a function'; }

    if( typeof context !== 'undefined' ) { 
        if( typeof context === 'object' && context instanceof Array === false ) { 
            if( typeof context[ functionName ] !== 'function' ) {
                throw context + '.' + functionName + ' is not a function';
            }
            args = Array.prototype.slice.call( arguments, 2 );

        } else {
            args = Array.prototype.slice.call( arguments, 1 );
            context = window;
        }

    } else {
        context = window;
    }

    namespaces = functionName.split( "." );
    func = namespaces.pop();

    for( var i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }

    return context[ func ].apply( context, args );
}

आपको एक स्ट्रिंग में संग्रहीत नाम से एक जावास्क्रिप्ट फ़ंक्शन को कॉल करने की अनुमति देगा, या तो नामांकित या वैश्विक, तर्क के साथ या बिना (एरे वस्तुओं सहित), सामने आई किसी भी त्रुटि पर प्रतिक्रिया प्रदान करना (उम्मीद है कि उन्हें पकड़ना)।

नमूना आउटपुट दिखाता है कि यह कैसे काम करता है:

// calling a global function without parms
executeFunctionByName( 'a' );
  /* OUTPUT:
  global func passed:
  */

// calling a global function passing a number (with implicit window context)
executeFunctionByName( 'a', 123 );
  /* OUTPUT:
  global func passed:
  -> 123
  */

// calling a namespaced function without parms
executeFunctionByName( 'ns.a' );
  /* OUTPUT:
  namespace func passed:
  */

// calling a namespaced function passing a string literal
executeFunctionByName( 'ns.a', 'No Such Agency!' );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  */

// calling a namespaced function, with explicit context as separate arg, passing a string literal and array 
executeFunctionByName( 'a', ns, 'No Such Agency!', [ 007, 'is the man' ] );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  -> 7,is the man
  */

// calling a global function passing a string variable (with implicit window context)
executeFunctionByName( 'a', name );
  /* OUTPUT:
  global func passed:
  -> nsa
  */

// calling a non-existing function via string literal
executeFunctionByName( 'n_s_a' );
  /* OUTPUT:
  Uncaught n_s_a is not a function
  */

// calling a non-existing function by string variable
executeFunctionByName( n_s_a );
  /* OUTPUT:
  Uncaught Snowden is not a function
  */

// calling an existing function with the wrong namespace reference
executeFunctionByName( 'a', {} );
  /* OUTPUT:
  Uncaught [object Object].a is not a function
  */

// calling no function
executeFunctionByName();
  /* OUTPUT:
  Uncaught function name not specified
  */

// calling by empty string
executeFunctionByName( '' );
  /* OUTPUT:
  Uncaught  is not a function
  */

// calling an existing global function with a namespace reference
executeFunctionByName( 'noSuchAgency', ns );
  /* OUTPUT:
  Uncaught [object Object].noSuchAgency is not a function
  */

डन्नो ... यह एक बहुत अच्छा प्रयास है, यह स्पष्ट है। लेकिन मेरे लिए "बहुत व्यापक" जैसा लगता है ...
TechNyquist

2
है ना? SO एक प्रश्न / उत्तर / शिक्षण मंच है। मैं ख़ुशी से उन सभी उदाहरणों को प्रदान करूँगा जिनके बारे में मैं उम्मीद कर सकता हूँ कि वे रोशनी से अवगत कराएँ। मेरे लिए, वह बात है
मैक

यदि आप किसी भी तरह फ़ंक्शन का नाम बदल रहे हैं, तो बस उसका उपयोग क्यों न करें?
डेटा

यह मेरे लिए काम नहीं करता है। मेरे पास एक नामांकित फ़ंक्शन abcd है जहां d फ़ंक्शन का नाम है। कॉल निष्पादित करेंफाइनेक्शनबायनाम ("abcd", विंडो) लाइन पर विफल रहता है जो चेक करता है if( typeof context[ functionName ] !== 'function' )क्योंकि संदर्भ - विंडो - परिभाषित है, एक ऑब्जेक्ट और एक सरणी है, लेकिन विंडो ['एब्सीडी'] मौजूद नहीं है क्योंकि स्वीकार किए गए समस्या के रूप में पहचाना गया था उत्तर: window["My.Namespace.functionName"](arguments); // fail
akousmata

12

आप कहां हैं, इसके आधार पर आप इसका उपयोग भी कर सकते हैं:

this["funcname"]();
self["funcname"]();
window["funcname"]();
top["funcname"]();
globalThis["funcname"]();

या, नोडज में

global["funcname"]()

9

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

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

उदाहरण:

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

8

सावधान रहे!!!

दो कारणों से जावास्क्रिप्ट में स्ट्रिंग द्वारा फ़ंक्शन को कॉल करने से बचने का प्रयास करना चाहिए:

कारण 1: कुछ कोड पर्यवेक्षक आपके कोड को मिटा देंगे क्योंकि वे फ़ंक्शन नामों को बदल देंगे, जिससे स्ट्रिंग अमान्य हो जाएगी।

कारण 2: कोड को बनाए रखना बहुत कठिन है जो इस पद्धति का उपयोग करता है क्योंकि स्ट्रिंग द्वारा बुलाए गए तरीकों के उपयोग का पता लगाना बहुत कठिन है।


7

यहाँ मेरा ईएस 6 दृष्टिकोण है जो आपको स्ट्रिंग के रूप में नाम से अपने फ़ंक्शन को कॉल करने में सक्षम बनाता है या यह फ़ंक्शन नाम है और आपको विभिन्न प्रकार के कार्यों के लिए विभिन्न प्रकार के तर्क पास करने में सक्षम बनाता है:

function fnCall(fn, ...args)
{
  let func = (typeof fn =="string")?window[fn]:fn;
  if (typeof func == "function") func(...args);
  else throw new Error(`${fn} is Not a function!`);
}


function example1(arg1){console.log(arg1)}
function example2(arg1, arg2){console.log(arg1 + "  and   " + arg2)}
function example3(){console.log("No arguments!")}

fnCall("example1", "test_1");
fnCall("example2", "test_2", "test3");
fnCall(example3);
fnCall("example4"); // should raise an error in console


6

सेटटाइमआउट का कोई उल्लेख नहीं देखकर आश्चर्य हुआ।

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

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

यह प्रश्न का उत्तर प्रदान नहीं करता है। किसी लेखक से स्पष्टीकरण मांगने या उसका स्पष्टीकरण देने के लिए, उनकी पोस्ट के नीचे एक टिप्पणी छोड़ दें - आप हमेशा अपने स्वयं के पोस्ट पर टिप्पणी कर सकते हैं, और एक बार आपके पास पर्याप्त प्रतिष्ठा होने पर आप किसी भी पोस्ट पर टिप्पणी करने में सक्षम होंगे ।
एस्ट्रो बीसी

कृपया इस बात का उदाहरण जोड़ें कि आप runMeकुछ तर्कों के साथ कैसे कॉल करेंगे ।
लेक्सिकोर

1
@lexicore मैंने एक समीक्षा कतार में हटाने के लिए मतदान किया , क्योंकि यह स्पष्ट रूप से प्रश्न का पर्याप्त जवाब नहीं देता है और यह अपने आप में बहुत कम मूल्य का है।
एस्ट्रो बीसी

1
इस पद्धति में संभावित रूप से बहुत बड़ी खामियां हैं, क्योंकि यह रेंडरिंग कतार के अंत में निष्पादन करता है , इस प्रकार यह कॉल अतुल्यकालिक है
पीटरएम

1
मुझे यह उत्तर पसंद है, यह मेरी आवश्यकताओं के लिए काम करता है।
क्विंटन

3

इसलिए, जैसा कि दूसरों ने कहा, निश्चित रूप से सबसे अच्छा विकल्प है:

window['myfunction'](arguments)

और जैसे जेसन बंटिंग ने कहा , यह काम नहीं करेगा यदि आपके फ़ंक्शन के नाम में कोई ऑब्जेक्ट शामिल हो:

window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work

तो यहाँ एक फ़ंक्शन का मेरा संस्करण है जो नाम से सभी कार्यों को निष्पादित करेगा (एक वस्तु या नहीं सहित):

my = {
    code : {
        is : {
            nice : function(a, b){ alert(a + "," + b); }
        }
    }
};

guy = function(){ alert('awesome'); }

function executeFunctionByName(str, args)
{
    var arr = str.split('.');
    var fn = window[ arr[0] ];
    
    for (var i = 1; i < arr.length; i++)
    { fn = fn[ arr[i] ]; }
    fn.apply(window, args);
}

executeFunctionByName('my.code.is.nice', ['arg1', 'arg2']);
executeFunctionByName('guy');


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

एक और OOP समाधान ...


2

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


2

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

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

2

मेरे कोड में एक बहुत ही समान बात है। मेरे पास एक सर्वर-जनित स्ट्रिंग है जिसमें एक फ़ंक्शन नाम शामिल है जिसे मुझे एक 3 पार्टी लाइब्रेरी के लिए कॉलबैक के रूप में पास करने की आवश्यकता है। इसलिए मेरे पास एक कोड है जो स्ट्रिंग लेता है और फ़ंक्शन के लिए "पॉइंटर" देता है, या यदि यह नहीं मिला है, तो इसे बंद कर दें।

मेरा समाधान " जेसन बंटिंग के बहुत उपयोगी कार्य " के समान था * , हालांकि यह ऑटो-निष्पादित नहीं करता है, और संदर्भ हमेशा खिड़की पर है। लेकिन इसे आसानी से संशोधित किया जा सकता है।

उम्मीद है कि यह किसी के लिए उपयोगी होगा।

/**
 * Converts a string containing a function or object method name to a function pointer.
 * @param  string   func
 * @return function
 */
function getFuncFromString(func) {
    // if already a function, return
    if (typeof func === 'function') return func;

    // if string, try to find function or method of object (of "obj.func" format)
    if (typeof func === 'string') {
        if (!func.length) return null;
        var target = window;
        var func = func.split('.');
        while (func.length) {
            var ns = func.shift();
            if (typeof target[ns] === 'undefined') return null;
            target = target[ns];
        }
        if (typeof target === 'function') return target;
    }

    // return null if could not parse
    return null;
}


1

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

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

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

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

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

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


रचनात्मक समाधान, लेकिन यह ऑब्जेक्ट या सरणी प्रकार के तर्कों के लिए काम नहीं करेगा।
डेनिस हेडेन

1
यह हुड के तहत eval का उपयोग कर रहा है ... और वास्तव में यह करने के लिए बुश के चारों ओर पिटाई कर रहा है
जुआन मेंडेस

1

सबसे आसान तरीका यह है कि इसे एक्सेस करना है जैसे तत्व है

window.ClientSideValidations.forms.location_form

वैसा ही है

window.ClientSideValidations.forms['location_form']

1

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

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

$( document ).ready(function() {

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

काम करने का उदाहरण: https://jsfiddle.net/suatatan/24ms0fna/4/


यह ठीक काम करता है और इसका इतना सरल
कार्लोस ई

1
और वास्तव में धीमा भी।
मार्को

1

यह मेरे लिए काम कर रहा है:

var command = "Add";
var tempFunction = new Function("Arg1","Arg2", "window." + command + "(Arg1,Arg2)");
tempFunction(x,y);

मेरी आशा है कि इससे काम हो जाए।


1

मुझे नहीं लगता कि आपको जटिल मध्यवर्ती कार्यों या eval की आवश्यकता है या खिड़की जैसे वैश्विक चर पर निर्भर होना चाहिए:

function fun1(arg) {
  console.log(arg);
}

function fun2(arg) {
  console.log(arg);
}

const operations = {
  fun1,
  fun2
};

let temp = "fun1";

try {
  // You have to use square brackets property access
  operations["fun1"]("Hello World");
  operations["fun2"]("Hello World");
  // You can use variables
  operations[temp]("Hello World");
} catch (error) {
  console.error(error);
}

यह आयातित कार्यों के साथ भी काम करेगा:

// mode.js
export function fun1(arg) {
  console.log(arg);
}

export function fun2(arg) {
  console.log(arg);
}
// index.js
import { fun1, fun2 } from "./mod";

const operations = {
  fun1,
  fun2
};

try {
  operations["fun1"]("Hello World");
  operations["fun2"]("Hello World");
} catch (error) {
  console.error(error);
}

0

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

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

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

1
क्यों? बिना स्पष्टीकरण के उत्तर सबसे अधिक संभावनाहीन हैं।
डैनियल डब्ल्यू।

0

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

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 देखें


0

बहुत उपयोगी उत्तर के लिए धन्यवाद। मैं अपने प्रोजेक्ट्स में जेसन बंटिंग फंक्शन का इस्तेमाल कर रहा हूं ।

मैंने इसे वैकल्पिक टाइमआउट के साथ उपयोग करने के लिए बढ़ाया, क्योंकि टाइमआउट अभ्यस्त काम को सेट करने का सामान्य तरीका। अभिषेकनोट का प्रश्न देखें

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

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

console.log('now wait')
executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.