Eval未声明函数

Eval not declaring functions

本文关键字:函数 未声明 Eval      更新时间:2023-09-26

我有一个代码字符串,它已经在其他地方使用Blockly为我创建了。在我看来,当我直接将其回声到一个页面时,它看起来是正确的:

function someName(){
    //some code
}
//more code
someName();

但是,当我对它调用eval时,函数调用本身不起作用。它声称该函数未定义。除了函数声明之外,其他一切都在工作。代码字符串本身已经设置好了,除非我做了大量的解析,否则我无法更改它。有没有更简单的方法来声明这些函数,以便代码可以调用它们?

测试用例(我实际使用的):

function test(){
    alert("This is a test");
}
test();

eval在一个非常特殊的环境中工作,在很多方面都很像本地范围。因此,如果您在函数中对该字符串调用eval,则someName函数将仅在该函数中声明,例如:

function doSomething(str) {
  eval(str);
  snippet.log(typeof someName); // "function"
}
doSomething("function someName() { }");
snippet.log(typeof someName); // "undefined"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

如果你想在全球范围内声明它,你必须做一些工作。Kangax写了一篇关于"全球eval"选项的精彩讨论。其中一个选项是David Flanagan建议的:

var geval = this.execScript || eval;

然后使用geval。这是因为IE具有在全局范围内工作的execScript,而在其他浏览器中,通过引用它的变量间接调用eval也使其在全局范围下工作。但是阅读这篇文章了解更多细节和选择。

function doSomething(str) {
  var geval = this.execScript || eval;
  geval(str);
  snippet.log(typeof someName); // "function"
}
doSomething("function someName() { }");
snippet.log(typeof someName); // "function"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

eval仅适用于如上所述的本地作用域,但是,您可以声明另一个版本的eval函数,并将其添加到窗口对象中,以便可以从全局上下文访问评估的代码函数:

// add global 
window.$eval = eval;
// now use $_eval version wherever you want 
function someFunction(){
   // use the $eval function 
   window.$eval('function doSomething() { }');
}
someFunction();
typeof doSomething == 'function' // true