Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript:闭包中的访问函数_Javascript_Closures - Fatal编程技术网

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中,它才会默认为
窗口