Javascript 从继承父作用域的字符串创建函数

Javascript 从继承父作用域的字符串创建函数,javascript,function,scope,Javascript,Function,Scope,在Javascript中,有没有一种方法可以从字符串(比如通过new function()构造函数)创建函数并让它继承父范围?例如: (function(){ function yay(){ } var blah = "super yay" yay.prototype.testy = new Function("alert(blah)") yay.prototype.hello = function(){alert(blah)} whee = ne

在Javascript中,有没有一种方法可以从字符串(比如通过new 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()也发出“超级耶”的警报?你是说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()
})()
(函数(){
函数yay(){
}
var blah=“超级耶”

yay.prototype.testy=新函数(eval(“alert(blah)”)/实际上,将
函数
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)') }
这对我来说似乎是可行的,没有任何评估数据来自任何不可信的来源。它只是用于缩小代码。

您不需要评估

您必须将blah连接到string函数,但是JavaScript会抱怨在连接之前没有“;”,这是因为在连接blah时,blah只是一些文本。您必须在变量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()
})()

这将警告“超级耶”两次!

为什么
whee.testy
不起作用,是因为使用
新函数声明函数(“警告(废话)”)
在当前闭包外部创建函数。由于
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();
})();

这会给你你想要的

var inputAction = "alert(blah)"; yay.prototype.testy = eval("(function(){ " + inputAction + "; })") var inputAction=“警报(废话)”; yay.prototype.testy=eval(((函数(){“+inputAction+”;})” 它基本上将您想要的操作包装在一个匿名函数中,在eval中得到完全的评估,但不是立即运行,而是包装在一个函数中


你可以在这里走得更远一点,但在不知道你想要完成什么的情况下,这很难说。

这是被否决的原因吗?我认为这是不可能的。我认为你不应该这样做。真的,这可能非常危险。从字符串创建函数的目的是什么?你想实现什么?
eval
是邪恶的!不要使用它!不要!这里有一个更好的解释为什么不使用eval:就像我说的:道德上客观的新函数(str)和eval(str)实际上是一样的。OP使用new Function()的方式是正确的-你不需要eval。在这里,我认为使用新函数(eval(“alert(blah)”)不起作用。好了,alert(blah)正在立即执行,而不是在调用函数时执行。函数和eval并不完全相同,这是一种不同的情况。函数不能访问创建它们的作用域的局部变量,而eval可以。但是OP必须非常确定字符串不包含任何恶意代码。我是inter以字符串赋值的方式来评价。是的,是的…eval是邪恶的,诸如此类。从OP围绕代码创建匿名函数的方式来看,这不是他第一天做JS。我只是使用eval/function来更好地压缩一些代码,不是用户输入的东西,但我只是有一些有很多函数的代码函数(e){var t=this;return e(t)?[t]:[]}内部代码非常少,函数(e){var t=this;return}.LOL..+1对您的注释-我喜欢您对典型的“eval is evil”advice的响应方式,但是如果我更新了“blah”的值,那么whee.testy()将警告错误的值。我知道它为什么不起作用,但有办法使其起作用吗?@antimater15:No..
new Function(string)
在全局范围内定义函数。这是出于设计。请改用匿名函数。 var inputAction = "alert(blah)"; yay.prototype.testy = eval("(function(){ " + inputAction + "; })")