【问题标题】:How/when is this anonymous function invoked?如何/何时调用此匿名函数?
【发布时间】:2010-09-29 14:41:46
【问题描述】:

我是 javascript 新手,我正在查看一些 Raphael 演示代码。我对它的工作原理感到困惑......

if (R) {
    (function (dx, dy, R, value) {
        var color = "hsb(" + [(1 - R / max) * .5, 1, .75] + ")";
...

据我所知,这是声明一个接受 4 个参数的匿名函数。这个函数没有名字怎么调用这个函数??

演示页面..http://raphaeljs.com/github/dots.html

JS文件..http://raphaeljs.com/github/dots.js

【问题讨论】:

  • js 文件有点长,我在里面找不到if (R) {。你能在这里发布更多代码吗?
  • 对不起,我想我不会包含足够的代码来弄清楚发生了什么,这就是我链接到源代码的原因。无论如何,现在已经回答了,谢谢! JS 文件不是 那么 长 - 只有几个屏幕已满 - 引用的部分刚好在一半以下。

标签: javascript anonymous-function raphael


【解决方案1】:

为了简要回答您的问题,它会在声明后立即调用。

你遗漏了一个重要的部分,函数定义的结尾:

})(leftgutter + X * (j + .5) - 60 - R, Y * (i + .5) - 10, R, data[o]);

这里说的是},它结束了函数,然后),结束了以(function开头的括号。如果剩下的看起来像一个参数列表,那是因为它是。

一个说明性的例子:

(function(arg){ alert(arg); })("Hi!");

【讨论】:

    【解决方案2】:

    您没有包含足够的代码来说明。看源码,这个方法是立即执行的。忽略函数的内容,看起来是这样的

    (function (dx, dy, R, value) {
    
    // ... stuff
    
    dot[0].onmouseover = function () {
        if (bg) {
            bg.show();
        } else {
            var clr = Raphael.rgb2hsb(color);
            clr.b = .5;
            dt.attr("fill", Raphael.hsb2rgb(clr).hex);
        }
        lbl.show();
    };
    
    // more stuff
    
    })(leftgutter + X * (j + .5) - 60 - R, Y * (i + .5) - 10, R, data[o]);
    

    这一切都发生在一个循环中,并且变量在事件处理程序方法中被引用。匿名方法创建了一个新范围,因此循环运行时的值被保留,而不是让每个事件处理程序都指向变量保存的最后一个值。

    【讨论】:

      【解决方案3】:

      一个匿名函数被动态创建和调用。一个简化的版本是

      function(a){<some method code>}(x);
      

      在此值x 在函数中作为a 传递。在您的示例中,稍后将调用该函数:

      (function (dx, dy, R, value) {
          var color = "hsb(" + [(1 - R / max) * .5, 1, .75] + ")";
          ...
      })(leftgutter + X * (j + .5) - 60 - R, Y * (i + .5) - 10, R, data[o]);
      

      【讨论】:

        【解决方案4】:

        28 行后调用:

        ...
            })(leftgutter + X * (j + .5) - 60 - R, Y * (i + .5) - 10, R, data[o]);
        

        这就是四个参数。

        如果你不给函数命名,你唯一能做的就是直接调用它或者将它传递给其他人。如果您熟悉事件侦听器,这是非常标准的:

        window.addEventListener("load", function(event) {
            document.body.innerHTML = "hello";
        }, false);
        

        在这种情况下,它用于控制变量的范围,以保证在循环的迭代完成后它们的值不会被重用。许多库将整个脚本包装在一个功能块中,只是为了创建一个新范围。 (与其他花括号语言不同,{ } 块单独创建新范围。)

        (function() {
            var foo; // guaranteed to not leak or interfere with someone else's foo
            // 6000 lines ...
        })();
        

        了解JavaScript Scope and Closures

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-04
          • 2022-01-22
          • 1970-01-01
          • 2022-11-26
          相关资源
          最近更新 更多