2010-02-18 2 views
5

В Javascript есть способ создать функцию из строки (например, через новый конструктор Function()) и наследовать ее родительскую область? Например:Создание функции из строки, которая наследует родительскую область

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

Есть ли способ сделать whee.testy() также предупреждение «супер яй»?

+2

Есть ли причина, по которой это было приостановлено? – cletus

+1

Я не думаю, что это возможно. – SLaks

+1

Думаю, вы не должны этого делать. На самом деле это может быть очень опасно. Какова цель создания функции из строки? Чего вы пытаетесь достичь? –

ответ

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

Это, кажется, работает для меня, и ни один из данных Эвальд не из любого ненадежного источника. Он просто используется для извлечения кода.

-1

Вы имеете в виду 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() 
})() 

Однако есть две морально неприемлемые особенности JS здесь. 1) eval «злой», и 2) код внутри eval может видеть переменные снаружи.

+0

'eval' is ** evil **! Не используйте его! Не надо! –

+0

И вот лучшее объяснение, почему бы не использовать eval: http://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil/198031#198031 –

+0

Как я уже сказал: морально неприемлемо –

1

На самом деле, совмещая function и eval должны делать то, что вы хотите:

// 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

Но OP должен быть ** очень ** уверен, что строка не содержит вредоносного кода Я заинтересован в том, как строка присваивается ее значение. –

+10

Да, да ... eval - это зло и все такое. Судя по тому, как OP создал анонимный функции вокруг его кода, это не его первый день, делающий JS. – levik

+0

Я просто использую eval/Function для лучшего сжатия некоторого кода, это не тот материал, который вводится пользователем, но у меня есть только код, в котором есть много функций с очень маленьким кодом внутри, function (e) {var t = это: return e (t)? [t]: []}, и существует значительная сумма байтов с функцией (e) {var t = this; return}. – antimatter15

-1

Вам не нужна оценка.

Вы должны объединить blah с строковой функцией, но JavaScript будет жаловаться, что нет ";" перед конкатенацией это происходит потому, что blah - это просто текст, когда вы его объединяете. Вы должны выйти два «\»»вокруг переменной бэ для того, чтобы сделать его похожим на строку с текстом в нем.

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

Это предупредит„супер-яй“два раза!

+0

Но если бы я обновил значение «blah», то whee.testy() предупредит неправильное значение. – antimatter15

0

Причины почему whee.testy не работает потому, что объявление функции с помощью new Function("alert(blah)") создает функцию вне текущего закрытия. Поскольку blah определяется внутри вашего закрытия, вы не имеете к нему доступа, и он бросает неопределенную ошибку.

Вот доказательство примера концепции:

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

Я знаю, почему это не сработает, но есть ли способ заставить его работать? – antimatter15

+0

@ antimatter15: No ... 'new Function (string)' определяет функцию в глобальной области. Это по дизайну. Вместо этого используйте анонимные функции. –

1

Это должно дать вам то, что вы хотите ...

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

Это в основном окружит Планируемое действие внутри анонимной функции, это становится полностью оценена на Eval, но не запускается сразу, он завернут в функцию.

Вы можете пойти немного дальше здесь, но не зная, чего вы хотите достичь, это трудно сказать.