क्या जावास्क्रिप्ट के साथ एक स्ट्रिंग से एक फ़ंक्शन बनाने का एक तरीका है?


107

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

var s = "function test(){
  alert(1);
}";

var fnc = aMethod(s);

यदि यह स्ट्रिंग है, तो मैं एक फ़ंक्शन चाहता हूं जिसे fnc कहा जाता है। और fnc();चेतावनी स्क्रीन चबूतरे।

eval("alert(1);") मेरी समस्या का समाधान नहीं है।

जवाबों:


73

मैंने स्ट्रिंग से फ़ंक्शन बनाने के लिए 4 अलग-अलग तरीकों से एक jsperf टेस्ट जोड़ा:

  • फ़ंक्शन क्लास के साथ RegExp का उपयोग करना

    var func = "function (a, b) { return a + b; }".parseFunction();

  • "वापसी" के साथ फंक्शन क्लास का उपयोग करना

    var func = new Function("return " + "function (a, b) { return a + b; }")();

  • आधिकारिक फ़ंक्शन निर्माता का उपयोग करना

    var func = new Function("a", "b", "return a + b;");

  • एवल का उपयोग करना

    eval("var func = function (a, b) { return a + b; };");

http://jsben.ch/D2xTG

2 परिणाम नमूने: यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें


@ केथप्रोग चिल डाउन;)। यह हमेशा खराब नहीं होता है, इस स्थिति की तरह, इस समय jsperf नीचे है, सौभाग्य से मैंने परिणाम स्क्रीनशॉट को डाउन करने से पहले जोड़ा, जब मुझे बल्क से टिप्पणी मिली।
फनाह

@KthProg FYI यह मॉडरेशन सिस्टम द्वारा उत्पन्न डिब्बाबंद प्रतिक्रिया थी :) यह एक कतार में पॉप अप होता है और हम पूर्वनिर्धारित समस्याओं के लिए जाँच करते हैं, जिनमें से एक यह टिप्पणी ठीक करने के लिए डिज़ाइन की गई है। यह एक कठिन और तेज़ नियम नहीं है, और आप देखेंगे कि टिप्पणी एक सुझाव के रूप में है न कि एक कमांड के रूप में।
डैन स्मिथ

174

स्ट्रिंग से फ़ंक्शन बनाने का एक बेहतर तरीका है Function:

var fn = Function("alert('hello there')");
fn();

इसका लाभ / नुकसान है कि मौजूदा दायरे में चर (यदि वैश्विक नहीं है) नवनिर्मित फ़ंक्शन पर लागू नहीं होता है।

तर्क पास करना भी संभव है:

var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'

5
सहमत हैं, Functionआप स्थानीय गुंजाइश को प्रदूषित नहीं करते हैं और यही वजह है कि evalइंजनों के लिए अनुकूलन इतना कठिन है ... ओपी उदाहरण के साथ, मैं चाहता हूं:var fnc = Function('return '+s)();
सीएमएस

मुझे लगता है कि यह संभवतः स्वीकृत उत्तर होना चाहिए। यह eval () की तुलना में अधिक सुरक्षित है।
ब्रायन रेनर

आप, मेरे दोस्त, कई अपवोट के लायक हैं। यह एक फ़ंक्शन ऑब्जेक्ट बनाने का लाभ है जिसे घटनाओं आदि के लिए सौंपा जा सकता है। उदाहरण के लिए: element.onclick = Function ("अलर्ट ('परीक्षण');");
रयान ग्रिग्स

1
@RyanGriggs आपके मामले में आपको "eval" कार्यक्षमता की आवश्यकता नहीं है, इसलिए इसे बेहतर रूप में लिखा गया है element.onclick = function() { alert("test"); }
लीकेनस्टाइन

1
आप मेरे उदाहरण से सही हैं। हालाँकि, यदि आप स्ट्रिंग्स में संग्रहीत मनमाने कार्यों को असाइन करना चाहते हैं, तो आपका तरीका सही है। यह वही है जो मैं वास्तव में करने की कोशिश कर रहा हूं। मेरे पास कई चर स्ट्रिंग चर में संग्रहीत हैं, और एक ऑन्कलिक कार्रवाई के लिए असाइन करना चाहते हैं।
रयान ग्रिग्स ने 15

38

तुम बहुत करीब हो।

//Create string representation of function
var s = "function test(){  alert(1); }";

//"Register" the function
eval(s);

//Call the function
test();

यहां वर्किंग फिडल है


मुझे पता था कि फ़ंक्शन घोषित किया गया था, लेकिन फ़ंक्शन नाम को कॉल करने का अनुमान नहीं लगा सका। बहुत बहुत धन्यवाद।
15

4
evalभविष्य के खोजकर्ताओं के लिए अनिवार्य चेतावनी: evalहैकर्स के लिए खामियां खोल सकते हैं: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… लेकिन अगर आप इसके खतरों को जानते हैं और इनसे बच सकते हैं, तो यह एक अच्छा सरल तरीका है एक स्ट्रिंग से एक फंक्शन बनाएं

क्या होगा अगर आपके पास डेटाबेस रिकॉर्ड से आने के बाद फ़ंक्शन का नाम नहीं है?
मार्सेल Djaman

13

हां, उपयोग Functionकरना एक महान समाधान है लेकिन हम थोड़ा आगे बढ़ सकते हैं और सार्वभौमिक पार्सर तैयार कर सकते हैं जो स्ट्रिंग को पार्स कर सकते हैं और इसे वास्तविक जावास्क्रिप्ट फ़ंक्शन में बदल सकते हैं ...

if (typeof String.prototype.parseFunction != 'function') {
    String.prototype.parseFunction = function () {
        var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
        var match = funcReg.exec(this.replace(/\n/g, ' '));

        if(match) {
            return new Function(match[1].split(','), match[2]);
        }

        return null;
    };
}

उपयोग के उदाहरण:

var func = 'function (a, b) { return a + b; }'.parseFunction();
alert(func(3,4));

func = 'function (a, b) { alert("Hello from function initiated from string!"); }'.parseFunction();
func();

यहाँ jsfiddle है


नमस्ते इस विधि के लिए तीर समारोह समर्थन का समर्थन करें?
सतीश कुमार

1
मुझे यह त्रुटि टाइपसीर्ट में प्राप्त हो रही है "संपत्ति 'पार्सफंक्शन' प्रकार 'स्ट्रिंग' पर मौजूद नहीं है।"
Cegone

11

में डायनामिक फ़ंक्शन नाम JavaScript

का उपयोग करते हुए Function

var name = "foo";
// Implement it
var func = new Function("return function " + name + "(){ alert('hi there!'); };")();
// Test it
func();
// Next is TRUE
func.name === 'foo'

स्रोत: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/

का उपयोग करते हुए eval

var name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'

का उपयोग करते हुए sjsClass

https://github.com/reduardo7/sjsClass

उदाहरण

Class.extend('newClassName', {
    __constructor: function() {
        // ...
    }
});

var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'

6

यह तकनीक अंततः eval विधि के बराबर हो सकती है, लेकिन मैं इसे जोड़ना चाहता था, क्योंकि यह कुछ के लिए उपयोगी हो सकता है।

var newCode = document.createElement("script");

newCode.text = "function newFun( a, b ) { return a + b; }";

document.body.appendChild( newCode );

यह कार्यात्मक रूप से आपके दस्तावेज़ के अंत में इस <स्क्रिप्ट> तत्व को जोड़ने की तरह है, जैसे:

...

<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>

</body>
</html>

3

new Function()अंदर वापसी के साथ प्रयोग करें और इसे तुरंत निष्पादित करें।

var s = `function test(){
  alert(1);
}`;

var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()


1

गतिशील तर्कों के साथ एक उदाहरण:

let args = {a:1, b:2}
  , fnString = 'return a + b;';

let fn = Function.apply(Function, Object.keys(args).concat(fnString));

let result = fn.apply(fn, Object.keys(args).map(key=>args[key]))

धन्यवाद। बहुत ही रोचक
Дмитрий Васильев
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.