2010-02-18 9 views
5

W języku JavaScript istnieje sposób na utworzenie funkcji z łańcucha znaków (na przykład przez nowy konstruktor Function()) i czy dziedziczy on nadrzędny zakres? Na przykład:Tworzenie funkcji z łańcucha znaków dziedziczącego zakres nadrzędny

(function(){ 
    function yay(){ 
    } 
    var blah = "super yay" 
    yay.prototype.testy = new Function("alert(blah)") 
    yay.prototype.hello = function(){alert(blah)} 
    whee = new yay(); 
    whee.hello() 
    whee.testy() 
})() 

Czy istnieje sposób, aby whee.testy() również ostrzec "super yay"?

+2

Czy jest jakiś powód, dla którego została odrzucona? – cletus

+1

Nie sądzę, że to możliwe. – SLaks

+1

Myślę, że nie powinieneś tego robić. Naprawdę może to być bardzo niebezpieczne. Jaki jest cel tworzenia funkcji z łańcucha? Co próbujesz osiągnąć? –

Odpowiedz

1
(function(){ 
    function yay(){ 
    } 
    var blah = "super yay" 
    yay.prototype.testy = eval("(function(){alert(blah)})")//new Function("alert(blah)") 
    yay.prototype.hello = function(){alert(blah)} 
    whee = new yay(); 
    whee.hello() 
    whee.testy() 
})() 

To wydaje się działać dla mnie, a żaden z danymi eval'd jest z dowolnego niezaufanych źródeł. Ma być użyty tylko do zminimalizowania kodu.

-1

Masz na myśli eval?

(function(){ 
    function yay(){ 
    } 
    var blah = "super yay" 
    yay.prototype.testy = new Function(eval("alert(blah)")) // <--------------- 
    yay.prototype.hello = function(){alert(blah)} 
    whee = new yay(); 
    whee.hello() 
    whee.testy() 
})() 

Są tu jednak dwie moralnie niepożądane cechy JS. 1) eval jest "zły", a 2) kod wewnątrz eval może zobaczyć zmienne na zewnątrz.

+0

'eval' jest ** evil **! Nie używaj go! Nie rób tego! –

+0

A tutaj jest lepsze wyjaśnienie, dlaczego nie używać eval: http://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil/198031#198031 –

+0

Tak jak powiedziałem: moralnie nieprzyzwoita –

1

Faktycznie, łącząc function i eval powinien robić to, co chcesz:

// blah exists inside the 'hello' function 
yay.prototype.hello = function(){ alert(blah) } 
// blah also exists inside the 'testy' function, and 
// is therefore accessible to eval(). 
yay.prototype.testy = function(){ eval('alert(blah)') } 
+0

Ale OP musi być ** bardzo ** pewny, że ciąg nie zawiera żadnego złośliwego kodu Interesuje mnie sposób, w jaki ciąg jest przypisany do jego wartości –

+10

Tak, tak ... eval jest zła i tak dalej. Sądząc po sposobie OP stworzył anonimowy funkcjonuje wokół swojego kodu, to nie jego pierwszy dzień robi JS. – levik

+0

Po prostu używam eval/Function, aby lepiej skompresować jakiś kod, to nie jest coś, co jest wprowadzane przez użytkownika, ale mam po prostu kod, w którym jest wiele funkcji z bardzo małym kodem w środku, function (e) {var t = this; return e (t)? [t]: []} i używa się znacznej ilości bajtów wraz z funkcją (e) {var t = this; return}. – antimatter15

-1

Nie potrzebujesz eval.

Musisz połączyć blah z funkcją string, ale JavaScript będzie narzekał, że nie ma ";" tuż przed konkatenacją jest to dlatego, że bla jest tylko pewnym tekstem, kiedy się go łączy. Musisz uciec dwa „\””wokół zmiennej bla w celu uczynienia go wyglądać sznurku z tekstem w nim.

(function(){ 
    function yay(){ 
    } 
var blah = "super yay" 

yay.prototype.testy = new Function("alert(\""+blah+"\")") 
yay.prototype.hello = function(){alert(blah)} 
whee = new yay(); 
whee.hello() 
whee.testy() 
})() 

będzie ten alert«super yay»dwa razy!

+0

Ale gdybym zaktualizowane wartości dla „bla”, a następnie whee.testy() by zaalarmować błędną wartość. – antimatter15

0

Powodem dlaczego whee.testy nie działa dlatego deklarowania funkcji przy użyciu new Function("alert(blah)") tworzy funkcję poza obecnymi zamknięcia. Od blah jest zdefiniowana wewnątrz zamknięcia, nie masz do niego dostęp, a to rzuca niezdefiniowany błąd.

Oto przykład dowodu koncepcji:

var blah = "global (window) scope"; 

(function(){ 
    function yay(){ 
    } 
    var blah = "closure scope"; 

    yay.prototype.testy = new Function("alert(blah)"); 
    yay.prototype.hello = function(){ alert(blah); } 
    whee = new yay(); 
    whee.hello(); 
    whee.testy(); 
})(); 
+0

Wiem, dlaczego to nie zadziała, ale czy jest jakiś sposób, żeby to zadziałało? – antimatter15

+0

@ antimatter15: Nie ... 'nowa funkcja (ciąg)' definiuje funkcję w zasięgu globalnym. Jest to zgodne z projektem. Zamiast tego użyj funkcji anonimowych. –

1

To powinno dać ci to, co chcesz ...

var inputAction = "alert(blah)"; 
yay.prototype.testy = eval("(function(){ " + inputAction + "; })")

Zasadniczo otacza swoją przeznaczone działanie wewnątrz anonimowej funkcji, to zostanie w pełni oceniona na eval, ale nie jest prowadzony od razu, jest zawinięty w funkcję.

Możesz pójść nieco dalej, ale nie wiedząc, co chcesz osiągnąć, trudno powiedzieć.

Powiązane problemy