जावास्क्रिप्ट में डायनामिक फ़ंक्शन नाम?


87

मेरे पास यह है:

this.f = function instance(){};

मैं यह करना चाहूंगा:

this.f = function ["instance:" + a](){};

10
आप नहीं कर सकते। लेकिन आपके पास हो सकता हैthis["instance"] = function() { }
रेयनोस


यह स्पष्ट करने के लिए कि रेयानोस क्या कह रहा था, आप कर सकते हैं this["instance" + a] = function() { }। यह मेरे लिए स्पष्ट नहीं था।
एंड्रयू

जवाबों:


7

अपडेट करें

जैसा कि दूसरों ने उल्लेख किया है, यह सबसे तेज़ और न ही सबसे अनुशंसित समाधान नहीं है। मार्कोस का समाधान नीचे जाने का रास्ता है।

आप eval का उपयोग कर सकते हैं:

var code = "this.f = function " + instance + "() {...}";
eval(code);

1
यही मैंने पूछा, धन्यवाद! (वैसे भी मैं इस सुविधा का उपयोग बहुत धीमी गति से नहीं
करूँगा

3
मुझे पता है कि यह ओपी ने क्या मांगा है, लेकिन यह एक भयानक विचार है। सिर्फ इसलिए कि आपका मतलब यह नहीं है कि आपको ऐसा कुछ करना चाहिए। बहुत बेहतर विकल्प हैं जो लगभग समान कार्यक्षमता वाले हैं।
थॉमस एडिंग

4
@ sg3s: क्या आप किसी अन्य समाधान का प्रस्ताव कर सकते हैं?
टॉम

2
@ sg3s: मेरी टिप्पणी का जवाब देने के लिए धन्यवाद! मुझे समझाएं कि मेरा क्या मतलब है, और मैं वास्तव में क्या पूछना चाहता हूं: मार्कोस का समाधान वास्तव में eval से काफी अलग है? क्या वास्तव में इससे कोई फ़र्क पड़ता है अगर आप किसी चीज़ को निकालते हैं या उसे फंक्शन कंस्ट्रक्टर को खिलाते हैं? यदि हां, तो क्या आप अंतर और उसके प्रभाव की व्याख्या कर सकते हैं? धन्यवाद!
टॉम

5
@ भविष्य के पाठकों के लिए: यह समाधान वास्तव में मार्कोस के जवाब से अलग नहीं है, वे दोनों का उपयोग करते हैं eval()( Functionनिर्माणकर्ता अंदर करता है)।
कापा

126

यह मूल रूप से इसे सबसे सरल स्तर पर करेगा:

"use strict";
var name = "foo";
var func = new Function(
     "return function " + name + "(){ alert('sweet!')}"
)();

//call it, to test it
func();

यदि आप अधिक फैंसी प्राप्त करना चाहते हैं, तो मेरे पास " जावास्क्रिप्ट में डायनामिक फ़ंक्शन नाम " पर एक लेख है ।


अच्छा काम! मैंने इसे अपने दम पर खोजा था और इन सवालों में से एक पर इसे पोस्ट करने वाला था, लेकिन आपने मुझे इसे हरा दिया। मैं हाल ही में backbone.js के साथ बहुत काम कर रहा हूं और अपने क्रोम डिबगर में हर जगह 'बच्चे' को देखकर थक गया हूं। यह उस समस्या को हल करता है। मुझे आश्चर्य है कि अगर कोई प्रदर्शन निहितार्थ हैं जैसे कि eval का उपयोग करना।
webXL

सुरक्षा निहितार्थ भी हैं। मुझे jSHint से "द फंक्शन कन्स्ट्रक्टर इवॉल्व है", इसलिए मैं इसे एक डिबग मोड चेक में लपेट रहा हूं, क्योंकि इसका उपयोग करने का एकमात्र कारण यही है। मुझे लगता है कि "सख्त का उपयोग करें" वैश्विक वस्तु के साथ किसी भी तरह की छेड़छाड़ को रोक देगा, लेकिन फंक्शन कंस्ट्रक्टर के किसी भी तर्क को संशोधित किया जा सकता है, और जो भी 'यह' सेट है।
webXL

हां, यह चरम स्थितियों के लिए जहां आपको मक्खी पर कुछ निर्माण करने की आवश्यकता होती है।
मार्कोस

1
मुझे ईमानदारी से लगता है कि stackoverflow.com/a/40918734/2911851 एक बेहतर समाधान है, फ़ंक्शन के शरीर को एक स्ट्रिंग के रूप में शामिल करने की आवश्यकता नहीं है (जब तक कि मैं कुछ याद नहीं कर रहा हूं, लेकिन मैंने बस कोशिश की और महान काम किया)।
जियान फ्रेंको ज़बारिनो २६'१।

2
AirBnB दृढ़ता से इसके खिलाफ सलाह देता है , क्योंकि फंक्शन कंस्ट्रक्टर evalजावास्क्रिप्ट का मूल्यांकन करने के लिए उपयोग करेगा - इस प्रकार आपके कोड को कमजोरियों के एक समूह के लिए खोल देगा।
फिलिप हेबर्ट

42

MDN जावास्क्रिप्ट संदर्भ [1] में दिए गए अनुसार आप Object.defineProperty का उपयोग कर सकते हैं:

var myName = "myName";
var f = function () { return true; };
Object.defineProperty(f, 'name', {value: myName, writable: false});
  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Description

2
यह के रूप में इरादा इस सेट नाम संपत्ति है, जबकि अगर मैं अपने ब्राउज़र में समारोह (नवीनतम फ़ायरफ़ॉक्स देव संस्करण) लॉग इन करें यह प्रिंट function fn(), fnमूल नाम किया जा रहा है। अजीब।
कियारा ग्रोवस्त्र

गूगल क्रोम सदाबहार पर एक ही टिप्पणी। संपत्ति ठीक से सेट है, लेकिन कंसोल में नाम, फ़ंक्शन का मूल नाम है। सी एफ 2ality.com/2015/09/… ऐसा लगता है कि फ़ंक्शन का नाम निर्माण में सौंपा गया है और इसे बदला नहीं जा सकता है?
user3743222

उस 2ality.com पेज पर अगले पैराग्राफ को देखें "फ़ंक्शन का नाम बदलना" [1] जो एमडीएन जावास्क्रिप्ट संदर्भ में मिली उसी तकनीक का वर्णन करता है। 1. 2ality.com/2015/09/…
डैरेन

35

हाल के इंजनों में, आप कर सकते हैं

function nameFunction(name, body) {
  return {[name](...args) {return body(...args)}}[name]
}



const x = nameFunction("wonderful function", (p) => p*2)
console.log(x(9)) // => 18
console.log(x.name) // => "wonderful function"


1
समाधान का पता लगाने की कोशिश में घंटों बिताने के बाद, मैंने गणना की गई संपत्ति के नाम के साथ एक वस्तु का उपयोग करने के लिए भी नहीं सोचा था। बिल्कुल वही जो मुझे चाहिए था। धन्यवाद!
लेवी रॉबर्ट्स

7
हालांकि यह काम करता है, मैंने Object.defineProperty(func, 'name', {value: name})अपने कोड में उपयोग करना शुरू कर दिया है , जैसा कि मुझे लगता है कि यह शायद थोड़ा और अधिक प्राकृतिक और समझने योग्य है।
किबरनेटिको

क्या यह ट्रांसप्लड कोड के साथ काम करता है? (बैबल या टाइपस्क्रिप्ट आउटपुट)
15

3
मेरे स्वयं के प्रश्न का उत्तर देना: {[expr]: val}एक वस्तु इनिशियलाइज़र है (जैसा कि JSON ऑब्जेक्ट है) जहां exprकुछ अभिव्यक्ति है; जो भी इसका मूल्यांकन करता है वह कुंजी है। {myFn (..){..} }के लिए आशुलिपि है {myFn: function myFn(..){..} }। ध्यान दें कि function myFn(..) {..}एक अनाम फ़ंक्शन की तरह एक अभिव्यक्ति के रूप में इस्तेमाल किया जा सकता है, केवल myFnएक नाम होगा। अंतिम [name]केवल ऑब्जेक्ट के सदस्य तक पहुंच रहा है (जैसे obj.keyया obj['key'])। ...प्रसार ऑपरेटर है। (मुख्य स्रोत: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
जेसन यंग

1
आपके विलाप के लिए धन्यवाद! नोट: यह के मूल्य को संरक्षित नहीं करता है this। उदाहरण के लिए obj={x:7,getX(){return this.x}}; obj.getX=nameFunction('name',obj.getX); obj.getX();काम नहीं करेगा। आप अपने जवाब को संपादित कर सकते हैं और function nameFunction(name, body) { return {[name](...args) {return body.apply(this, args)}}[name] }इसके बजाय उपयोग कर सकते हैं!
टीएस

11

मुझे लगता है कि यहाँ ज्यादातर सुझाव अडॉप्ट, हैली सॉल्यूशन या रैपर का उपयोग करके उप-रूपी हैं। ES2015 के नाम चरों और गुणों के लिए सिंटैक्टिक स्थिति से अनुमानित हैं।

तो यह ठीक काम करेगा:

const name = 'myFn';
const fn = {[name]: function() {}}[name];
fn.name // 'myFn'

नामित फ़ंक्शन फ़ैक्टरी विधियों को बनाने के प्रलोभन का विरोध करें क्योंकि आप फ़ंक्शन को बाहर से पास करने में सक्षम नहीं होंगे और इसके नाम का अनुमान लगाने के लिए इसे सिंटैक्टिक स्थिति में वापस कर देंगे। फिर पहले ही बहुत देर हो चुकी है। यदि आपको वास्तव में इसकी आवश्यकता है, तो आपको एक आवरण बनाना होगा। किसी ने यहाँ किया है, लेकिन यह समाधान कक्षाओं के लिए काम नहीं करता है (जो भी कार्य हैं)।

उल्लिखित सभी वेरिएंट के साथ अधिक गहराई से उत्तर यहां लिखा गया है: https://stackoverflow.com/a/9479081/633921


1
यह उत्तर stackoverflow.com/a/41854075/3966682 कैसे सुधार करता है ?
15:

1
@ d4nyll मैंने पहले ही उत्तर दिया है कि: यह एक आवरण बनाता है, जो स्टेटफुल फ़ंक्शंस ("यह" का उपयोग करके कार्य करता है) उर्फ ​​कक्षाएं।
Albin

@ एएलबीएन एफडब्ल्यूआईडब्ल्यू, यह मेरे लिए बिल्कुल स्पष्ट नहीं है कि आपका जवाब यह कैसे कहता है। किसी भी तरह, यह जानना अच्छा है।
जेसन यंग

@JasonYoung "फंक्शन फैक्ट्री के तरीकों को बनाने के प्रलोभन का विरोध करें क्योंकि आप फ़ंक्शन को बाहर से पास नहीं कर पाएंगे और इसे अपने नाम को समझने के लिए सिंटैक्टिक स्थिति में वापस ले जा सकते हैं। फिर पहले ही बहुत देर हो चुकी है। यदि आपको वास्तव में इसकी आवश्यकता है, तो आपको एक आवरण बनाना है। किसी ने यहां किया, लेकिन वह समाधान कक्षाओं के लिए काम नहीं करता है (जो भी कार्य हैं)। "
एल्बिन

3

व्हाट अबाउट

this.f = window["instance:" + a] = function(){};

एकमात्र दोष यह है कि इसकी toSource विधि में कार्य एक नाम नहीं दर्शाता है। यह आमतौर पर केवल डिबगर के लिए एक समस्या है।


यह अच्छा नहीं है क्योंकि एकमात्र कारण मुझे क्लासेस के नाम को तेजी से देखना है। मेरे सिस्टम में हर वर्ग एक अनाम फ़ंक्शन है और डीबगर में मुझे अनाम दिखाता है ..
Totty.js

1
ठीक है, तो आप प्रश्न में कह सकते हैं।
एंटोनियो

3

सिंटैक्स का function[i](){}अर्थ है कि वे गुण मानों के साथ एक ऑब्जेक्ट है, जो फ़ंक्शन, function[]नाम द्वारा अनुक्रमित हैं [i]
इस प्रकार
{"f:1":function(){}, "f:2":function(){}, "f:A":function(){}, ... } ["f:"+i]

{"f:1":function f1(){}, "f:2":function f2(){}, "f:A":function fA(){}} ["f:"+i]फ़ंक्शन नाम पहचान को संरक्षित करेगा। के बारे में नीचे दिए नोट्स देखें :

इसलिए,

javascript: alert(
  new function(a){
    this.f={"instance:1":function(){}, "instance:A":function(){}} ["instance:"+a]
  }("A") . toSource()
);

({f:(function () {})})फ़ायरफ़ॉक्स में प्रदर्शित करता है।
(यह इस समाधान के रूप में लगभग एक ही विचार है , केवल यह एक सामान्य वस्तु का उपयोग करता है और अब कार्य के साथ विंडो ऑब्जेक्ट को सीधे पॉप्युलेट नहीं करता है।)

यह विधि स्पष्ट रूप से पर्यावरण को पॉप्युलेट करती है instance:x

javascript: alert(
  new function(a){
    this.f=eval("instance:"+a+"="+function(){})
  }("A") . toSource()
);
alert(eval("instance:A"));

प्रदर्शित करता है

({f:(function () {})})

तथा

function () {
}

हालांकि संपत्ति फ़ंक्शन fएक संदर्भ देता है anonymous functionऔर नहींinstance:x , यह विधि इस समाधान के साथ कई समस्याओं से बचाती है ।

javascript: alert(
  new function(a){
    eval("this.f=function instance"+a+"(){}")
  }("A") . toSource()
);
alert(instanceA);    /* is undefined outside the object context */

केवल प्रदर्शित करता है

({f:(function instanceA() {})})
  • एम्बेडेड :जावास्क्रिप्ट को function instance:a(){}अमान्य बनाता है ।
  • एक संदर्भ के बजाय, फ़ंक्शन की वास्तविक पाठ परिभाषा पार्स और व्याख्या की गई है eval

निम्नलिखित समस्याग्रस्त नहीं है,

  • instanceAसमारोह के रूप में उपयोग के लिए सीधे उपलब्ध नहीं होताinstanceA()

और इसलिए मूल समस्या के संदर्भ में बहुत अधिक संगत है।

इन विचारों को देखते हुए,

this.f = {"instance:1": function instance1(){},
          "instance:2": function instance2(){},
          "instance:A": function instanceA(){},
          "instance:Z": function instanceZ(){}
         } [ "instance:" + a ]

ओपी उदाहरण के शब्दार्थ और वाक्य विन्यास के साथ वैश्विक कंप्यूटिंग वातावरण को यथासंभव बनाए रखता है।


यह रिज़ॉल्यूशन केवल स्थिर नामों के लिए या ES6 डायनेमिक प्रॉपर्टी नामों के साथ काम करता है। उदाहरण के लिए (name => ({[name]:function(){}})[name])('test')काम करता है लेकिन (name => {var x={}; x[name] = function(){}; return x[name];})('test')ऐसा नहीं करता
विलियम लीयुंग

3

सबसे अधिक वोट किए गए उत्तर को पहले ही परिभाषित [स्ट्रिंग] फ़ंक्शन बॉडी मिल गई है। मैं पहले से ही घोषित समारोह का नाम बदलने के समाधान की तलाश में था और आखिरकार एक घंटे के संघर्ष के बाद मैंने इससे निपटा। यह:

  • अल्रेदी घोषित समारोह लेता है
  • इसे [स्ट्रिंग] के साथ पार्स करता है .toString() विधि के
  • फिर नाम (नामांकित फ़ंक्शन का) को अधिलेखित करता है या नए और (जब अनाम)function और के बीच जोड़ता है(
  • फिर नए नामांकित फ़ंक्शन को new Function()निर्माता के साथ बनाता है

function nameAppender(name,fun){
  const reg = /^(function)(?:\s*|\s+([A-Za-z0-9_$]+)\s*)(\()/;
  return (new Function(`return ${fun.toString().replace(reg,`$1 ${name}$3`)}`))();
}

//WORK FOR ALREADY NAMED FUNCTIONS:
function hello(name){
  console.log('hello ' + name);
}

//rename the 'hello' function
var greeting = nameAppender('Greeting', hello); 

console.log(greeting); //function Greeting(name){...}


//WORK FOR ANONYMOUS FUNCTIONS:
//give the name for the anonymous function
var count = nameAppender('Count',function(x,y){ 
  this.x = x;
  this.y = y;
  this.area = x*y;
}); 

console.log(count); //function Count(x,y){...}


2

ECMAScript 2015 (ES6) द्वारा प्रदान की गई वस्तु शाब्दिक एक्सटेंशन का उपयोग करके किसी वस्तु के गतिशील तरीके बनाए जा सकते हैं:

const postfixes = ['foo', 'bar'];

const mainObj = {};

const makeDynamic = (postfix) => {
  const newMethodName = 'instance: ' + postfix;
  const tempObj = {
    [newMethodName]() {
      console.log(`called method ${newMethodName}`);
    }
  }
  Object.assign(mainObj, tempObj);
  return mainObj[newMethodName]();
}

const processPostfixes = (postfixes) => { 
  for (const postfix of postfixes) {
    makeDynamic(postfix); 
  }
};

processPostfixes(postfixes);

console.log(mainObj);

ऊपर कोड चलाने का आउटपुट है:

"called method instance: foo"
"called method instance: bar"
Object {
  "instance: bar": [Function anonymous],
  "instance: foo": [Function anonymous]
}

यह अधिक महत्वपूर्ण है: o={}; o[name]=(()=>{})इसके बजायfunction <<name>>(){}
Sancarn

2

मौजूदा अनाम फ़ंक्शन का नाम सेट करने के लिए :
(@ मार्कोस के उत्तर पर आधारित)

var anonymous = function() { return true; }

var name = 'someName';
var strFn = anonymous.toString().replace('function ', 'return function ' + name);
var fn = new Function(strFn)();

console.log(fn()); // —> true

डेमो

नोट : यह मत करो /


जब आप इसे ठीक करते हैं। लेकिन आपको अपने तर्क का सौजन्य देना चाहिए ताकि हम आपसे सीख सकें। ओपी "गतिशील" फ़ंक्शन नामों के लिए पूछता है। यह ऐसा करने का एक तरीका है, लेकिन मैं कभी भी सिफारिश नहीं करता और न ही मैंने कभी ऐसा किया।
ओनोर येल्ड्रिम

1

इसे प्राप्त करने के दो तरीके हैं, और उनके पास अपने पेशेवरों और विपक्ष हैं।


name संपत्ति की परिभाषा

किसी फ़ंक्शन की अपरिवर्तनीय name संपत्ति को परिभाषित करना

पेशेवरों

  • नाम के लिए हर पात्र उपलब्ध है। (उदाहरण। () 全 {}/1/얏호/ :D #GO(@*#%! /*)

विपक्ष

  • फ़ंक्शन का सिंटैक्टिक ("अभिव्यंजक") नाम उसके nameगुण मान के अनुरूप नहीं हो सकता है ।

समारोह अभिव्यक्ति मूल्यांकन

एक नामित फ़ंक्शन अभिव्यक्ति बनाना और इसके साथ मूल्यांकन करनाFunction निर्माण ।

पेशेवरों

  • फ़ंक्शन का सिंटैक्टिक ("अभिव्यंजक") नाम हमेशा उसके nameगुण मान से मेल खाता है ।

विपक्ष

  • नाम के लिए व्हाट्सएप (और आदि) उपलब्ध नहीं हैं।
  • अभिव्यक्ति-इंजेक्शन योग्य (उदाहरण के लिए (){}/1//, इनपुट के लिए , अभिव्यक्ति एक फ़ंक्शन के बजाय return function (){}/1//() {}देता NaNहै।)।

const demoeval = expr => (new Function(`return ${expr}`))();

// `name` property definition
const method1 = func_name => {
    const anon_func = function() {};
    Object.defineProperty(anon_func, "name", {value: func_name, writable: false});
    return anon_func;
};

const test11 = method1("DEF_PROP"); // No whitespace
console.log("DEF_PROP?", test11.name); // "DEF_PROP"
console.log("DEF_PROP?", demoeval(test11.toString()).name); // ""

const test12 = method1("DEF PROP"); // Whitespace
console.log("DEF PROP?", test12.name); // "DEF PROP"
console.log("DEF PROP?", demoeval(test12.toString()).name); // ""

// Function expression evaluation
const method2 = func_name => demoeval(`function ${func_name}() {}`);

const test21 = method2("EVAL_EXPR"); // No whitespace
console.log("EVAL_EXPR?", test21.name); // "EVAL_EXPR"
console.log("EVAL_EXPR?", demoeval(test21.toString()).name); // "EVAL_EXPR"

const test22 = method2("EVAL EXPR"); // Uncaught SyntaxError: Unexpected identifier

1

यदि आप __callPHP में फ़ंक्शन की तरह एक गतिशील फ़ंक्शन करना चाहते हैं , तो आप प्रॉक्सी का उपयोग कर सकते हैं।

const target = {};

const handler = {
  get: function (target, name) {
    return (myArg) => {
      return new Promise(resolve => setTimeout(() => resolve('some' + myArg), 600))
    }
  }
};

const proxy = new Proxy(target, handler);

(async function() {
  const result = await proxy.foo('string')
  console.log('result', result) // 'result somestring' after 600 ms
})()

1

आप इस तरह डायनामिक फंक्शन नाम और मापदंडों का उपयोग कर सकते हैं।

1) फ़ंक्शन को अलग करें और इसे कॉल करें

let functionName = "testFunction";
let param = {"param1":1 , "param2":2};

var func = new Function(
   "return " + functionName 
)();

func(param);

function testFunction(params){
   alert(params.param1);
}

2) फ़ंक्शन कोड डायनामिक परिभाषित करें

let functionName = "testFunction(params)";
let param = {"param1":"1" , "param2":"2"};
let functionBody = "{ alert(params.param1)}";

var func = new Function(
    "return function " + functionName + functionBody 
)();

func(param);

0

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

// returns the function named with the passed name
function namedFunction(name, fn) {
    return new Function('fn',
        "return function " + name + "(){ return fn.apply(this,arguments)}"
    )(fn)
}

0

यह उपयोगिता फ़ंक्शन कई कार्यों को एक (एक कस्टम नाम का उपयोग करके) मर्ज करता है, केवल आवश्यकता यह है कि प्रदान किए गए फ़ंक्शन ठीक से अपने स्कूप की शुरुआत और अंत में "नए पंक्तिबद्ध" हैं।

const createFn = function(name, functions, strict=false) {

    var cr = `\n`, a = [ 'return function ' + name + '(p) {' ];

    for(var i=0, j=functions.length; i<j; i++) {
        var str = functions[i].toString();
        var s = str.indexOf(cr) + 1;
        a.push(str.substr(s, str.lastIndexOf(cr) - s));
    }
    if(strict == true) {
        a.unshift('\"use strict\";' + cr)
    }
    return new Function(a.join(cr) + cr + '}')();
}

// test
var a = function(p) {
    console.log("this is from a");
}
var b = function(p) {
    console.log("this is from b");
}
var c = function(p) {
    console.log("p == " + p);
}

var abc = createFn('aGreatName', [a,b,c])

console.log(abc) // output: function aGreatName()

abc(123)

// output
this is from a
this is from b
p == 123

0

डैरेन के उत्तर और कर्निटिको के उत्तर के संयोजन में मेरे पास बेहतर भाग्य था ।

const nameFunction = function (fn, name) {
  return Object.defineProperty(fn, 'name', {value: name, configurable: true});
};

/* __________________________________________________________________________ */

let myFunc = function oldName () {};

console.log(myFunc.name); // oldName

myFunc = nameFunction(myFunc, 'newName');

console.log(myFunc.name); // newName

नोट: Function.name 1 के लिए मानक ES2015 कल्पना से मेल खाने के लिए configurableसेट हैtrue

यह विशेष रूप से इस के समान वेबपैक में एक त्रुटि के आसपास होने में मदद करता है

अद्यतन: मैं इसे एक npm पैकेज के रूप में प्रकाशित करने के बारे में सोच रहा था, लेकिन सिंदोरसोरस से यह पैकेज बिल्कुल वैसा ही काम करता है।

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name

0

मैंने इस मुद्दे पर बहुत संघर्ष किया। @ एलबिन समाधान ने विकास करते समय एक आकर्षण की तरह काम किया, लेकिन जब मैंने इसे उत्पादन में बदला तो यह काम नहीं किया। कुछ डिबगिंग के बाद मुझे एहसास हुआ कि मुझे क्या हासिल करना है। मैं CRA (क्रिएट-रिएक्शन-ऐप) के साथ ES6 का उपयोग कर रहा हूं, जिसका अर्थ है कि यह वेबपैक द्वारा बंडल किया गया है।

कहते हैं कि आपके पास एक फ़ाइल है जो आपके लिए आवश्यक कार्यों का निर्यात करती है:

myFunctions.js

export function setItem(params) {
  // ...
}

export function setUser(params) {
  // ...
}

export function setPost(params) {
  // ...
}

export function setReply(params) {
  // ...
}

और आपको गतिशील रूप से इन कार्यों को कहीं और कॉल करने की आवश्यकता है:

myApiCalls.js

import * as myFunctions from 'path_to/myFunctions';
/* note that myFunctions is imported as an array,
 * which means its elements can be easily accessed
 * using an index. You can console.log(myFunctions).
 */

function accessMyFunctions(res) {
  // lets say it receives an API response
  if (res.status === 200 && res.data) {
    const { data } = res;
    // I want to read all properties in data object and 
    // call a function based on properties names.
    for (const key in data) {
      if (data.hasOwnProperty(key)) {
        // you can skip some properties that are usually embedded in
        // a normal response
        if (key !== 'success' && key !== 'msg') {
          // I'm using a function to capitalize the key, which is
          // used to dynamically create the function's name I need.
          // Note that it does not create the function, it's just a
          // way to access the desired index on myFunctions array.
          const name = `set${capitalizeFirstLetter(key)}`;
          // surround it with try/catch, otherwise all unexpected properties in
          // data object will break your code.
          try {
            // finally, use it.
            myFunctions[name](data[key]);
          } catch (error) {
            console.log(name, 'does not exist');
            console.log(error);
          }
        }
      }
    }
  }
}


0

गतिशील कार्यों की सूची के साथ ऑब्जेक्ट बनाने का सबसे अच्छा तरीका है:

const USER = 'user';

const userModule = {
  [USER + 'Action'] : function () { ... }, 
  [USER + 'OnClickHandler'] : function () { ... }, 
  [USER + 'OnCreateHook'] : function () { ... }, 
}


-2

मुझे यहाँ स्पष्ट याद आ रही है, लेकिन सिर्फ नाम जोड़ने में क्या गलत है? उनके नाम की परवाह किए बिना कार्य किए जाते हैं। नामों का इस्तेमाल सिर्फ डांटने के कारणों के लिए किया जाता है। यदि आप इसे किसी वैरिएबल पर असाइन करते हैं, और यह स्कोप में है, तो इसे कॉल किया जा सकता है। टोपी होती है, आपका एक चर निष्पादित होता है जो एक फ़ंक्शन होता है। यदि आपके पास डीबग करते समय पहचान के कारणों के लिए एक नाम होना चाहिए, तो इसे कीवर्ड फ़ंक्शन और शुरुआती ब्रेस के बीच डालें।

var namedFunction = function namedFunction (a,b) {return a+b};

alert(namedFunction(1,2));
alert(namedFunction.name);
alert(namedFunction.toString());

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

(function(renamedFunction) {

  alert(renamedFunction(1,2));
  alert(renamedFunction.name);
  alert(renamedFunction.toString());
  alert(renamedFunction.apply(this,[1,2]));


})(function renamedFunction(){return namedFunction.apply(this,arguments);});

function namedFunction(a,b){return a+b};


फ़ंक्शन / विधि nameउपयोगी है क्योंकि यह अब चर और गुणों से अनुमान लगाया गया है। इसका उपयोग स्टैक के निशान में भी किया जाता है। Ex var fn = function(){}; console.log(fn.name)। यह अपरिवर्तनीय है, इसलिए आप इसे बाद में नहीं बदल सकते। यदि आप एक कारखाना विधि लिखते हैं जो सभी कार्यों को नाम देता है fnतो यह डीबगिंग को कठिन बना देगा।
एल्बिन


-9

यह सबसे अच्छा समाधान है, तो बेहतर है new Function('return function name(){}')()

सबसे तेज़ समाधान है:

यहाँ छवि विवरण दर्ज करें

var name = 'FuncName'
var func = eval("(function " + name + "(){})")

जो कोई भी इसे पढ़ रहा है, इस उत्तर का अनुसरण करें।
मैक्समैक्समैक्सिमस

1
@ माजिदरीफ आदमी सही है, यह सबसे तेज है: jsperf.com/dynamicfunctionnames/1 । हालांकि अब तक सबसे सुरक्षित नहीं है।
संस्कार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.