javascript:闭包中的访问函数
我有一个变量中的函数名,但所有内容都在闭包中。我想用这个变量调用函数,类似这样javascript:闭包中的访问函数,javascript,closures,Javascript,Closures,我有一个变量中的函数名,但所有内容都在闭包中。我想用这个变量调用函数,类似这样 (function(func) { this[func]() ; // doesn't work function bar() {} function foo() {} })('bar') ; 像这样的事情是可能的还是我应该,例如,将函数添加到一个变量中,比如 (function(func) { var ns = {
(function(func) {
this[func]() ; // doesn't work
function bar() {}
function foo() {}
})('bar') ;
像这样的事情是可能的还是我应该,例如,将函数添加到一个变量中,比如
(function(func) {
var ns = {
bar: function() {},
foo: function() {}
};
ns[func]() ; // OK
})('bar') ;
无法使用
[]
语法按名称访问当前词法范围中声明的变量和函数-只能根据另一个变量的内容动态查找属性键(根据第二个示例)
唯一的解决办法是求助于eval
,这几乎从来都不是一个好主意
例外情况适用于全局范围内声明的变量和函数-这些实际上是窗口的属性
(new function() {
this.a = function(x) {
document.getElementById('out').innerHTML += x;
}
})['a']('boom.');
闭门造车,一切保密。通常,闭包中的这个
只是指窗口
。但是,您可以先将其转换为匿名对象,在“闭包”中“公开”项目,而不会污染全局空间。这允许您在对象消失之前对其进行一次且仅一次的方法调用
您可以执行普通的对象操作,比如使用私有的词汇变量,只公开您想要公开的方法
(new function() {
var a = function(x) { document.getElementById('out').innerHTML += x; }
var b = function() { a(d); }
var c = function() { /* ... */ }
var d = "whatever";
// expose two of them ..
this.a = a;
this.b = b;
})['a']('boom.');
根据我的经验,将函数放在闭包中是将其声明为“私有”的一种方式,这样外部的任何东西都无法访问它。此外,值得一看代码的精简方式:
之前:
(function() {
function privateFn(var1, var2) {
//TODO
}
return {
publicFn: function() { }
}
})();
之后:
(function() {
function _a(_0, _1) {
}
return {
publicFn: function() { }
}
})();
请注意,privateFn
是如何不再存在的?根据语言的定义,minifier知道没有任何东西可以通过名称或其他方式在外部访问该函数。您似乎想公开一个函数。您的代码毫无意义。“你到底想实现什么?”基里尔说得很有道理。在第一个示例中,如何使用“变量函数”名称调用foo
或bar
?例如,window[foo]()
在全局范围内运行良好,这个[foo]()
没有。这个
在闭包中只是窗口
对象。你最好使用第二种方法。OP想从闭包内部访问函数。@Roy,他仍然有一个观点。如果他缩小代码,代码将被破坏,因为缩小器不会“重命名”他的字符串。@Derija93缩小和作为属性键的字符串不会混合,你必须告诉缩小器哪些函数不能重命名。@Alnitak这是真的,肯定是Katana314应该提到的。@Derija93在任何情况下,迷你程序不会触及属性的名称,因此对于词汇范围内的变量,这并不重要,因为使用变量作为名称访问它们的唯一方法是使用eval
。。。。半真半假。请参阅我的答案。@svidgen在您的答案中,您没有声明词典范围的函数,您已经向对象添加了属性。您是否建议您不能在对象中创建词典范围的变量/函数?或者,从暴露词汇“成员”的逻辑飞跃太大了。。。不,我是说你的答案似乎一点也不相关。OP希望通过名称从该范围内调用一个词汇范围内的函数,其中名称本身是一个变量。如果没有eval
,或者在OP的第二个代码块中使用属性名,则无法执行此操作。与此问题的链接不清楚。@你的意思是什么?你的代码与OP的第二个提议的代码块相比没有任何优势,后者工作得非常完美。@svidgen我不同意。OP的第二个代码块是完全可以理解的,可以简单地扩展到包含一些词汇范围的变量,并且所有这些都不需要记住调用new
来允许使用this
。和Derija93一样,我认为他的版本更简单,也同样灵活!哦,这个
在闭包中可以是(通常是)任何变量-这个
取决于闭包的调用方式。只有在iLife中,它才会默认为窗口
。