最新消息:

如何访问作为命名空间的函数内部变量

JavaScript相关 knitter 99浏览 0评论

原文标题:《Functions as Namespaces, and How to Peek Inside》
原文地址:http://www.davidflanagan.com/2009/11/functions-as-na.html

很精彩的技巧,通过闭包和eval()的使用,达到标题中的功能。

[js]
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]
以上代码是我们经常用到的技巧:赋值时通过执行一个匿名函数来防止一些代码变量污染全局空间,并且函数内部可以写很复杂的实现而无需担心对外部的影响。

但是有些情况下我们得到的js代码是一串字符串——例如,用xhr读取到的js代码。倘若想要使用它,可以用eval(),还可以用更方便的Function()构造器。
[js]
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]
所以,通过这种技巧,哪怕是从一段js字符串源代码来赋值,也是可行的:
[js]
var code = "return 3;";
var f = new Function(code);
var i = f(); //i是3
[/js]
但是这里却有一个问题。因为是由Function()构造函数而来的,相当于创造了一个密封的命名空间(所有代码都在一个匿名function内执行),我们无法从外部访问它。倘若里面有一些定义的类或者函数之类的东西,那就难办了。比如这样:
[js]
var code = "function Test() {};";
var f = new Function(code);
f();</li>
//这相当于执行了以下方法:
function f() {
function Test() {
}
};
f();
[/js]
内部定义了一个Test类,我们很难访问到它。不过这里有个技巧——这也是本篇要介绍的主角——可以通过闭包+eval()结合使用来绕过这种限制。
[js]
var code = "function Test() { alert(‘a test’); };";
var f = new Function(code + "return function(s) { return eval(s); };")(); //关键!还有后面的括号!
var Test = f("Test");
new Test();
[/js]
如何?内部的Test类成功从外部创建了。关键就在于第2行,这里有个小小限制,第3行传入的参数需和要使用的内部变量名相等。外部的Test其实相当于密封函数内的Test的一个copy,没想明白的话根据代码倒着走一遍就ok了。

转载请注明:文档库 » 如何访问作为命名空间的函数内部变量

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址