Как / когда вызывается эта анонимная функция? - PullRequest
1 голос
/ 29 сентября 2010

Я новичок в 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

Ответы [ 4 ]

2 голосов
/ 29 сентября 2010

Чтобы кратко ответить на ваш вопрос, он вызывается сразу после объявления.

Вы пропустили важную часть, конец определения функции:

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

То, что это говорит, это }, который завершает функцию, затем ), который заканчивает скобку, открывающуюся с (function Если то, что остается, выглядит как список аргументов, это потому, что так оно и есть.

Наглядный пример:

(function(arg){ alert(arg); })("Hi!");
1 голос
/ 29 сентября 2010

Анонимная функция создается и вызывается на лету.Упрощенная версия будет

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]);
1 голос
/ 29 сентября 2010

Она вызывается через 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 и замыкания

1 голос
/ 29 сентября 2010

Вы не включили достаточно кода, чтобы сказать. Глядя на источник, этот метод выполняется немедленно. игнорируя содержимое функции, это выглядит так

(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]);

все это происходит внутри цикла, а переменные указываются в методе обработчика события. анонимный метод создает новую область видимости, поэтому значения во время выполнения цикла сохраняются, вместо того чтобы каждый обработчик события указывал на самое последнее значение, которое содержит переменная.

...