原文标题:《Functions as Namespaces, and How to Peek Inside》
原文地址:http://www.davidflanagan.com/2009/11/functions-as-na.html
很精彩的技巧,通过闭包和eval()的使用,达到标题中的功能。
var value = (function() { // Wrapper function creates a local scope or namespace
// your code goes here
return value; // Export a value from the namespace
})(); // Invoke the wrapper function to run your code
以上代码是我们经常用到的技巧:赋值时通过执行一个匿名函数来防止一些代码变量污染全局空间,并且函数内部可以写很复杂的实现而无需担心对外部的影响。
但是有些情况下我们得到的js代码是一串字符串——例如,用xhr读取到的js代码。倘若想要使用它,可以用eval(),还可以用更方便的Function()构造器。
var code = "alert(1);"; // A string of JS code to evaluate
var f = new Function(code); // Wrap it in a function
f(); // And run the function
//army注:这段代码和下面是完全等同的:
function f() {
alert(1);
}
f();
所以,通过这种技巧,哪怕是从一段js字符串源代码来赋值,也是可行的:
var code = "return 3;"; var f = new Function(code); var i = f(); //i是3
但是这里却有一个问题。因为是由Function()构造函数而来的,相当于创造了一个密封的命名空间(所有代码都在一个匿名function内执行),我们无法从外部访问它。倘若里面有一些定义的类或者函数之类的东西,那就难办了。比如这样:
var code = "function Test() {};";
var f = new Function(code);
f();
//这相当于执行了以下方法:
function f() {
function Test() {
}
};
f();
内部定义了一个Test类,我们很难访问到它。不过这里有个技巧——这也是本篇要介绍的主角——可以通过闭包+eval()结合使用来绕过这种限制。
var code = "function Test() { alert('a test'); };";
var f = new Function(code + "return function(s) { return eval(s); };")(); //关键!还有后面的括号!
var Test = f("Test");
new Test();
如何?内部的Test类成功从外部创建了。关键就在于第2行,这里有个小小限制,第3行传入的参数需和要使用的内部变量名相等。外部的Test其实相当于密封函数内的Test的一个copy,没想明白的话根据代码倒着走一遍就ok了。

哈,你还自己详细演示了代码
这样还不如直接使用eval。。。
我说错了,一开始没看仔细,sorry…