Подтвердить что ты не робот

Javascript анонимная функция

У меня есть код javascript (внутри объекта):

toggle: function() {
    var me = this;
    var handler = function() { me.progress() };
    me.intervalId = setInterval(handler, me.intervalTime);
    //...More code
}

Я как бы новичок в javascript, поэтому, делая это, насколько я могу судить, фактически передает переменную me в анонимную функцию. Я хотел посмотреть, есть ли более декларативный способ сделать это? Я хотел что-то по линии:

var handler = (function(o) { o.progress();})(this));

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

UPDATE:

Источником моей проблемы было/это мое нечеткое понимание области и закрытия в javascript. Я нашел эту статью, чтобы помочь мне понять немного больше.

4b9b3361

Ответ 1

Вы можете использовать ".bind()":

var handler = function() { this.progress(); }.bind(this);

У новых браузеров есть "bind()", а Документы Mozilla имеют прочную реализацию, которую вы можете использовать для исправления старых браузеров.

Ответ 2

Причина

var handler = (function(o) { o.progress();})(this));

не работает, потому что он сразу вызывает функцию анона, поэтому сразу вызывает o.progress() и присваивает возвращаемое значение функции анона (undefined) на handler. Вам нужно вернуть фактическую функцию из внешней функции:

handler = (function(me){
    return function(){
        return me.progress();
    }
}(this));

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


BTW, если функция прогресса не имеет никаких вызовов this внутри нее, достаточно сделать handler = this.progress (без парнеров).

Ответ 3

Анонимная функция имеет доступ к me, потому что она объявлена ​​внутри внешней функции (функция toggle); он закрывается внешней функцией.

Ваша функция handler вызывается setInterval, которая передает ровно нулевые аргументы. Это означает, что вы не можете использовать параметры в самой функции обработчика.

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

toggle: function() {
    var me = this;
    var handler = (function (o) { return function() { o.progress() }; })(me);
    me.intervalId = setInterval(handler, me.intervalTime);
    //...More code
}

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

function createProgressHandler(o) {
    return function() {
        o.progress();
    };
}

// ...

toggle: function() {
    var me = this;
    var handler = createProgressHandler(me);
    me.intervalId = setInterval(handler, me.intervalTime);
    //...More code
}

Ответ 4

У вас есть закрытие. Функция, созданная и назначенная handler, сохраняет ссылку на объект me. Это обычный, повседневный JavaScript, и что способ закрытия обычно работает.

Ответ 5

Вы пытались вернуть такую ​​функцию?

var handler = function(o){
   return function(){
      o.progress();
   }
}(me);

Теперь вы можете позвонить:

handler();