【问题标题】:javascript: access function in closure [closed]javascript:闭包中的访问函数[关闭]
【发布时间】:2013-05-23 19:40:58
【问题描述】:

我在一个变量中有一个函数的名称,但一切都在一个闭包中。有了这个变量,我想调用函数,像这样

(function(func) {
      this[func]() ;         // doesn't work

      function bar() {}
      function foo() {}
})('bar') ;

这样的事情可能吗,或者我应该,例如,将函数添加到变量中,比如

(function(func) {        
      var ns = {
          bar: function() {},
          foo: function() {}
      };

      ns[func]() ;         // OK
})('bar') ;

【问题讨论】:

  • 你的代码没有意义。你到底想达到什么目的?
  • @Kirill 非常有意义。在第一个示例中,如何使用“变量函数”名称调用 foobar?例如。 window[foo]() 在全局范围内工作正常,this[foo]() 不行。
  • this 在闭包内不过是window 对象。你最好使用第二种方法。

标签: javascript closures


【解决方案1】:

不能使用[] 语法按名称访问在当前词法范围内声明的变量和函数 - 只能根据另一个变量的内容动态查找属性键(根据您的第二个示例)。

解决这个问题的唯一方法是求助于eval,这几乎不是一个好主意。

一个例外适用于在全局范围内声明的变量和函数 - 它们实际上是 window 的属性。

【讨论】:

  • ... 半真半假。看我的回答。
  • @svidgen 在你的回答中你没有声明一个词法范围的函数,你已经向一个对象添加了一个属性。
  • 您是否建议您不能在对象中创建词法范围的变量/函数?或者说暴露一个词汇“成员”的逻辑飞跃太大了? ...
  • 不,我是说您的回答似乎与远程无关。 OP 想要在该范围内调用 lexically scoped 函数 by name,其中名称本身就是一个变量。没有eval就无法完成。
  • 或通过使用属性名称,根据他的第二个代码块。
【解决方案2】:

根据我的经验,将函数放入闭包中是一种将其声明为“私有”的方式 - 这样外部的任何东西都无法访问它。此外,值得研究的是代码被缩小的方式:

之前:

(function() {
    function privateFn(var1, var2) {
        //TODO
    }
    return {
        publicFn: function() { }
    }
})();

之后:

(function() {
    function _a(_0, _1) {

    }
    return {
        publicFn: function() { }
    }
})();

注意privateFn 是如何不再存在的?根据语言的定义,缩小器知道没有任何东西可以在外部访问该函数 - 通过名称或其他方式。您似乎想公开您的一项功能。

【讨论】:

  • OP 想要从闭包内部访问函数。
  • @dystroy 他还是有道理的。如果他缩小他的代码,它将中断,因为缩小器不会“重命名”他的字符串。
  • @Derija93 缩小和作为属性键的字符串不能混合,你必须告诉缩小器哪些函数不要重命名。
  • @Alnitak 这是真的,绝对是 Katana314 应该提到的。
  • @Derija93 在任何情况下,压缩器都不会触及属性的名称,因此对于词法范围的变量来说这并不重要,因为使用变量名称访问它们的唯一方法是使用eval
【解决方案3】:

类似这样的:

(new function() {
    this.a = function(x) {
        document.getElementById('out').innerHTML += x;
    }
})['a']('boom.');

http://jsfiddle.net/CT4du/1/

闭包使所有内容保持私密。通常,闭包中的this 只是指window。但是,您可以通过首先将其转换为匿名对象来在“闭包”中“公开”项目而不会污染全局空间。这允许您在对象消失之前对对象进行一个且只有一个方法调用...

你可以做普通的对象事情,比如使用私有的、词法变量并只公开你想要公开的方法。

(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.');

【讨论】:

  • 问题链接不清楚。
  • @dystroy 你是什么意思?
  • 与 OP 提出的第二个代码块相比,您的代码没有任何优势,该代码块运行良好。
  • @svidgen 我不同意。 OP 的第二个代码块是完全可以理解的,并且可以简单地扩展为包含一些词法范围的变量,并且所有这些都不需要记住调用new 以允许使用this。和 Derija93 一样,我认为他的版本更简单,而且它同样灵活
  • 哦,闭包中的this 可以是(而且经常是)任何变量——this 取决于闭包是如何调用的。只有在 IIFE 中,它才会 默认window
猜你喜欢
  • 2022-07-06
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多