从字符串创建的函数不会看到父作用域

cyx*_*xou 1 javascript

在我的应用程序中,我有一些功能包装在一个模块中.要运行这些函数中的任何一个,我向服务器发送一个请求,该请求使用类似"foo({bar:'baz'})"的字符串进行响应.然后我从这个字符串创建一个新函数并运行它.问题是新函数没有看到它所在的范围.这是一个简化的例子:

var foo = (function () {

  function bar (fnbody) {
    // this one runs
    var baz = function() { greet1(); };
    baz();

    // this one does not
    var doit = new Function(fnbody);
    doit();
  }

  function greet1() {
    alert('ALOHA!');
  }
  function greet2() {
    alert('SAWADEE!');
  }


  return {
    bar: bar
  };

})();

foo.bar('greet2();');
Run Code Online (Sandbox Code Playgroud)

这是jsBin.

任何人都可以解释为什么greet2()没有定义?我怎样才能使这种事情保持功能greet1和greet2私有模块?

提前致谢!

小智 6

这只是Function构造函数的工作原理.使用它创建的函数是在全局范围内创建的,而不是在定义它的本地范围内创建的.

这是预期的行为.您必须使用eval()从可以访问局部变量的字符串创建函数.

ES5 15.3.2.1新函数(p1,p2,...,pn,body)开始,最后一步如下:

"11.返回一个按照13.2中的规定创建的新Function对象,将P作为FormalParameterList和body 传递给FunctionBody.将全局环境作为Scope参数传递,并将严格作为Strict标志传递."


Tha*_*you 5

来自MDN功能

注意:使用Function构造函数创建的函数不会为其创建上下文创建闭包; 它们总是在全球范围内创建.运行它们时,它们只能访问自己的局部变量和全局变量,而不能访问调用Function构造函数的范围.这与使用eval和函数表达式的代码不同.

如果您希望服务器/客户端调用任何一方的函数,也许您应该查看某种远程过程调用(RPC).

JSON-RPC可能会让您感兴趣.还有一个很大的实现列表供您选择.