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. Я нашел эту статью, чтобы помочь мне понять немного больше.
Ответы
Ответ 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();