मैं जावास्क्रिप्ट में डायनामिक रूप से नामित विधि कैसे कहूं?


113

मैं गतिशील रूप से कुछ जावास्क्रिप्ट बनाने पर काम कर रहा हूं जिसे एक वेब पेज में डाला जाएगा क्योंकि इसका निर्माण किया जा रहा है।

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

उदाहरण के लिए:

Listbox1 शामिल हैं:

  • Colours
  • Shapes

यदि Coloursचुना गया है, तो यह एक populate_Coloursविधि को कॉल करेगा जो दूसरे को पॉप्युलेट करता है listbox

मेरे प्रश्न को स्पष्ट करने के लिए: मैं उस populate_Coloursकॉल को जावास्क्रिप्ट में कैसे करूँ ?


मैं इसके खिलाफ एक 'पॉपुलेट' पद्धति में स्थानीय शाखाएँ रखने के पक्ष में सिफारिश करूँगा। यह इसे और अधिक परीक्षण योग्य बना देगा और "हैकी" कम लगेगा
आरोन पॉवेल

जवाबों:


208

यह मानकर कि populate_Coloursविधि वैश्विक नेमस्पेस में है, आप निम्नलिखित कोड का उपयोग कर सकते हैं, जो दोनों का शोषण करता है कि सभी ऑब्जेक्ट गुणों तक पहुँचा जा सकता है जैसे कि ऑब्जेक्ट एक साहचर्य सरणी थे, और यह कि सभी वैश्विक ऑब्जेक्ट वास्तव में windowहोस्ट ऑब्जेक्ट के गुण हैं ।

var method_name = "Colours";
var method_prefix = "populate_";

// Call function:
window[method_prefix + method_name](arg1, arg2);

9
जवाब देने के लिए धन्यवाद। 'विंडो' बिट ने वास्तव में मुझे तब तक फेंक दिया जब तक कि मैंने इसे गॉगल नहीं किया और पाया कि वैश्विक वस्तुएं विंडो ऑब्जेक्ट का हिस्सा हैं। अब समझ में आता है! धन्यवाद। FYI करें मुझे इसके बारे में एक अच्छा पृष्ठ मिला है यहाँ devlicio.us/blogs/sergio_pereira/archive/2009/02/09/…
क्रिस बी

3
मैंने कुछ इसी तरह के कार्यों को छोड़कर जो मैं लक्ष्य कर रहा था वह jQuery के "fn" नामस्थान में था। उदाहरण के लिए,$.fn[method_prefix + method_name](arg1, arg2);
codec

1
अच्छा लगा। एक जोड़ने के लायक try/ catchब्लॉक, शायद।
लीगी

यह कुछ के लिए स्पष्ट हो सकता है, लेकिन उन है कि यह काम करने के लिए नहीं मिल सकता है के लिए: अपने $(function () {और window.loadकोड के बाहर समारोह फेंक :)
स्टेन धूम्रपान

1
@peter क्योंकि स्क्वायर ब्रैकेट इस संदर्भ में प्रॉपर्टी एक्सेसर्स नहीं हैं, लेकिन एक ऐरे को दर्शाते हैं। Arrays फ़ंक्शन नहीं हैं, इसलिए आप उन्हें कॉल नहीं कर सकते।
user4642212

39

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

एक क्लीनर विधि, जो वैश्विक नाम स्थान को बहुत कम प्रदूषित करती है, स्पष्ट रूप से कार्यों को सीधे एक सरणी में डालती है:

var dyn_functions = [];
dyn_functions['populate_Colours'] = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions['populate_Shapes'](1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions.populate_Shapes(1, 2);

यह सरणी वैश्विक होस्ट ऑब्जेक्ट के अलावा कुछ ऑब्जेक्ट की संपत्ति भी हो सकती है, जिसका अर्थ है कि आप प्रभावी रूप से कई JS लाइब्रेरी जैसे jQuery do के रूप में अपना स्वयं का नाम स्थान बना सकते हैं। यह संघर्ष को कम करने के लिए उपयोगी है यदि / जब आप एक ही पृष्ठ में कई अलग-अलग उपयोगिता पुस्तकालय शामिल करते हैं, और (आपके डिज़ाइन के अन्य भाग) अन्य पृष्ठों में कोड का पुन: उपयोग करना आसान बना सकते हैं।

आप किसी वस्तु का उपयोग भी कर सकते हैं, जैसे कि आपको क्लीनर मिल सकता है:

var dyn_functions = {};
dyn_functions.populate_Colours = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions.populate_Shapes(1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions['populate_Shapes'](1, 2);

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

var dyn_functions = {
           populate_Colours:function (arg1, arg2) { 
                // function body
           };
         , populate_Shapes:function (arg1, arg2) { 
                // function body
           };
};

संपादित करें: निश्चित रूप से कार्यक्षमता के बड़े ब्लॉकों के लिए आप ऊपर बहुत सामान्य "मॉड्यूल पैटर्न" का विस्तार कर सकते हैं जो एक संगठित तरीके से कोड सुविधाओं को एन्कैप्सलेट करने का एक लोकप्रिय तरीका है।


यह साफ रखने का एक अच्छा तरीका है। हालांकि मैं विधि को कैसे कहूंगा? खिड़की करेगा [dyn_functions ['populate_Colours'] (arg1, arg2) काम?
क्रिस बी

अपने स्वयं के प्रश्न का उत्तर देते हुए - मैंने बस खिड़की का परीक्षण किया है [dyn_functions ['populate_Colours'] (arg1, arg2)]; और यह वास्तव में काम करता है।
क्रिस बी

4
जैसा कि epascarello बताते हैं, आपको आमतौर पर "विंडो" की आवश्यकता नहीं होती है - "dyn_functions ['populate_Colours'] (arg1, arg2);" काम करेगा। वास्तव में, वैश्विक वस्तु के नाम को शामिल न करने से कोड अधिक पोर्टेबल हो जाएगा यदि आप दिनचर्या लिख ​​रहे हैं जो कभी भी एक वेब ब्राउज़र के अलावा JS वातावरण में उपयोग किया जा सकता है। हालांकि इसका एक अपवाद है: यदि आपके पास एक फ़ंक्शन में dyn_functions नामक एक स्थानीय चर है, तो आपको अधिक विशिष्ट होने की आवश्यकता होगी जिसे आप संदर्भित कर रहे हैं, लेकिन इस स्थिति को वैसे भी सबसे अच्छा नामकरण सम्मेलनों () होने से बचा जाता है।
डेविड स्पिललेट

1
चूंकि यह पोस्ट '09 से है, आप शायद अब तक यह जानते हैं, लेकिन आप एक सरणी बना रहे हैं, फिर सरणी के गुणों को निर्दिष्ट कर रहे हैं (अनुक्रमित नहीं)। आप के रूप में अच्छी तरह से ऐसा var dyn_functions = {};कर सकते हैं ताकि आप एक सरणी बनाने की जरूरत नहीं है ... हालांकि यह एक बड़ा मुद्दा नहीं है।
डेविड शेरेट

अति जटिल जवाब लेकिन काम करता है। मुझे लगता है कि परिदृश्य के लिए संसाधन लोड जहां मेरे पास पैटर्न वाले कार्यों की श्रृंखला है और मुझे निष्पादन का चयन करने के लिए निर्णय पेड़ की आवश्यकता है, यह कार्य कार्य करने के लिए अत्यधिक जटिल हो सकता है। यद्यपि, यदि मैं अपनी कक्षा की वस्तु को निकाल रहा था, तो यह वस्तु को परिभाषित करने का पसंदीदा तरीका होगा।
गोल्डबिशप

30

मैं इस प्रयोजन के लिए / / का उपयोग नहीं करने की सलाह दूंगा । इसके बजाय, इसे इस तरह से करें: globalwindoweval

हैंडलर के गुणों के रूप में सभी विधियों को परिभाषित करें:

var Handler={};

Handler.application_run = function (name) {
console.log(name)
}

अब इसे इस तरह कहें

var somefunc = "application_run";
Handler[somefunc]('jerry');

आउटपुट: जेरी


17

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

function MyClass() {
    this.abc = function() {
        alert("abc");
    }
}

var myObject = new MyClass();
myObject["abc"]();

5

एक के भीतर ServiceWorkerया Worker, की जगह windowके साथ self:

self[method_prefix + method_name](arg1, arg2);

श्रमिकों के पास DOM तक कोई पहुंच नहीं है, इसलिए windowएक अमान्य संदर्भ है। इस उद्देश्य के लिए समान वैश्विक गुंजाइश पहचानकर्ता है self


2

मैं खिड़की का उपयोग करने की सलाह नहीं दूंगा क्योंकि कुछ अन्य उत्तर सुझाते हैं। thisतदनुसार उपयोग और गुंजाइश।

this['yourDynamicFcnName'](arguments);

एक और साफ-सुथरी ट्रिक अलग-अलग स्कॉप्स के भीतर कॉल कर रही है और इसका उपयोग विरासत के लिए किया जा रहा है। मान लें कि आपने फ़ंक्शन को नेस्टेड कर दिया है और वैश्विक विंडो ऑब्जेक्ट तक पहुंच चाहते हैं। आप ऐसा कर सकते हैं:

this['yourDynamicFcnName'].call(window, arguments);

1

हाय यह कोशिश करो,

 var callback_function = new Function(functionName);
 callback_function();

यह मापदंडों को खुद ही संभाल लेगा।


बिना किसी संदर्भ के त्रुटि - functionName परिभाषित नहीं है
brianlmerritt

@brianlmerritt के लिए आपको मान को परिभाषित करना होगा functionName... जवाब देने वाले ने यह धारणा बनाई कि आपने पहले से ही परिभाषित किया था।
गोल्डबिशप

ऐसा लगता है कि इस उद्देश्य के लिए नए फ़ंक्शन () का उपयोग नहीं किया जा सकता है।
JCH77

-1

यहाँ एक काम है और जाँच के लिए सरल समाधान है एक समारोह के अस्तित्व और गतिशील है कि समारोह triaging एक और समारोह से;

ट्रिगर समारोह

function runDynmicFunction(functionname){ 

    if (typeof window[functionname] == "function"  ) { //check availability

        window[functionname]("this is from the function it "); //run function and pass a parameter to it
    }
}

और आप अब इस तरह से php का उपयोग करके गतिशील रूप से फ़ंक्शन उत्पन्न कर सकते हैं

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

अब आप फ़ंक्शन को डायनामिकली जेनरेट किए गए इवेंट का उपयोग करके कॉल कर सकते हैं

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynmicFunction(\"".$name_frm_somware."\");'>";

?>

सटीक HTML कोड आपको चाहिए

<input type="button" value="Button" onclick="runDynmicFunction('runThis_func');">

-3

इसके साथ प्रयास करें:

var fn_name = "Colours",
fn = eval("populate_"+fn_name);
fn(args1,argsN);

इस पैटर्न का उपयोग करने के निहितार्थ क्या हैं? मैंने पढ़ा है कि evalफ़ंक्शन के इसके उपयोग से संबंधित कुछ गंभीर दुष्प्रभाव हैं। मैं आमतौर पर इससे दूर रहने की कोशिश करता हूं, जब तक कि यह अंतिम उपाय न हो।
गोल्डबिशप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.