2009-08-13 14 views
16

Mam funkcję i jej zawartość jako ciąg znaków.wykonywanie funkcji anonimowych utworzonych przy użyciu JavaScript eval()

var funcStr = "function() { alert('hello'); }"; 

Teraz robię eval(), aby faktycznie uzyskać tę funkcję w zmiennej.

var func = eval(funcStr); 

Jeśli dobrze pamiętam, w Chrome i Opera, po prostu dzwoniąc

func(); 

powoływać tę funkcję, a wpis ten został wyświetlony.

Jednak w innych przeglądarkach tak nie było. nic się nie stało.

Nie chcę argumentować, która metoda jest właściwa, ale jak mogę to zrobić? Chcę móc wywołać metodę variable(); wykonać funkcję zapisaną w tej zmiennej.

+0

Zastanawiam się, dlaczego potrzebujesz anonimowej funkcji reprezentowanej jako literał łańcuchowy, w przeciwieństwie do zwykłej funkcji nazwanej? –

+0

FYI: Definiuję własny skrypt do mojej aplikacji internetowej. Piszę interpreter i muszę konstruować funkcje JS w locie, a następnie tworzyć z nich rzeczywiste funkcje wykonywalne. –

+0

dlaczego nie napisałbyś tłumacza w tradycyjny sposób? – Breton

Odpowiedz

30

Jak chodzi?

var func = new Function('alert("hello");'); 

Aby dodać argumenty do funkcji:

var func = new Function('what', 'alert("hello " + what);'); 
func('world'); // hello world 

Należy pamiętać, że funkcje są obiektami i mogą być przypisane do dowolnej zmiennej, ponieważ są one:

var func = function() { alert('hello'); }; 
var otherFunc = func; 
func = 'funky!'; 

function executeSomething(something) { 
    something(); 
} 
executeSomething(otherFunc); // Alerts 'hello' 
+0

To jest zarówno elegancki sposób na to, i działa we wszystkich przeglądarkach. Dzięki :) –

6

Spróbuj

var funcStr = "var func = function() { alert('hello'); }"; 

eval(funcStr); 

func(); 
+0

hej, Dzięki, że zadziałało! Ale wygląda to trochę dziwnie, aby zrobić to w ten sposób: D. –

4

pomocą eval tak:

var func = eval('(' + funcStr + ')'); 
+0

Tak myślałem na początku, ale jestem prawie pewien, że dotyczy to tylko obiektów. – karim79

+0

Ponadto, niezależnie od tego, czy jest to właściwa czy niewłaściwa metoda ..., nie działa w IE. –

+0

Funkcje również są obiektami. Działa z nawiasami. – Blixt

13

IE nie może eval funkcje (Prawdopodobnie ze względów bezpieczeństwa).

Najlepszym rozwiązaniem jest umieścić funkcję w tablicy, tak:

var func = eval('[' + funcStr + ']')[0]; 
+1

Heh ... Sneaky sneaky! – Blixt

+0

Tak, może. Jednak literał funkcyjny nie jest instrukcją, więc potrzebuje wokół nich nawiasów, jest czystszy niż twoje rozwiązanie macierzowe –

+1

@Juan: Wrong; nie może. Spróbuj 'javascript: alert (eval ('(function() {return 3;})'));' – SLaks

0

Co działa również jest

var myFunc = function(myParam){ 
    // function body here 
} 
7

Zdaję sobie sprawę, to jest stary, ale był to jedyny poprawny wynik pojawiające się w moim google szuka wartości anonimowych ciągów funkcji javascript.

W końcu zorientowałem się, jak to zrobić z posta na grupie jokery Google.

eval("false||"+data) 

gdzie dane są kryteria funkcji jak "function() {return 123;}"

Do tej pory próbowałem to tylko w IE8 i FF8 (przeglądarki na moim komputerze osobistym), ale Wierzę, że jquery używa tego wewnętrznie, więc powinien działać prawie wszędzie.

+0

Nie rozumiem, dlaczego wszyscy inni wydają się nie mieć tego problemu. To jest złoto, dzięki! – Shwouchk

0

EVAL bez eval() ...

function evalEx(code){ 
    var result,D=document,S=D.createElement('script'), 
    H=D.head||D.getElementsByTagName['head'][0], 
    param=Array.prototype.slice.call(arguments); 
    code='function evalWE(){'+code+'}'; 
    S.innerText===''?S.innerText=code:S.textContent=code; 
    H.appendChild(S); 
    result=evalWE.apply(this,param); 
    H.removeChild(S); 
    return result 
} 

przykład użycia:

ABC=evalEx('return "ABC"'); 
nine=evalEx('return arguments[1]+arguments[2]',4,5); 
+0

haha, właśnie podałeś mi powód, dla którego Google Packaged Apps nie dopuszcza wbudowanego javascript w HTML: http://developer.chrome.com/extensions/contentSecurityPolicy.html – nraynaud

0

Prostym przykładem określające funkcję łańcucha, eval() ing, i przechodzącą w parametru jednocześnie bezpośrednio wywołanie funkcji (i zrzucania prowadzić do uzyskania konsola):

console.log('eval: %s', eval("(function(foo) { return foo.bar; })")({"bar": "12345"}));

To daje wyjście jak poniżej.

eval: 12345

3

Rozwiązaliśmy ten problem poprzez przygotowanie uniwersalnego funkcji parsera, które przekształcają ciąg do rzeczywistej funkcji javascript:

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

Przykłady użycia:

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

here jest jsfiddle