2009-08-14 4 views
4

Я хочу передать массив объектов функции setTimer в Javascript.Как передать объект Array функции setInterval

setTimer("foo(object_array)",1000); 

получение ошибки по этому коду.

** Примечание: ** Извините! некоторая коррекция в моем вопросе: возможно ли это в функции setInterval().

ответ

17

Используйте анонимную функцию вместо строки на первом параметре функции setTimeout или setInterval:

// assuming that object_array is available on this scope 
setInterval(function() { foo(object_array); }, 1000); 

Почему это работает:

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

Эта языковая функция называется closures.

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

Eval обеспечивает прямой доступ к компилятору JavaScript и выполняет код, он передается с привилегиями вызывающего абонента, а также с помощью Eval неоднократно/широко (то есть ваша setInterval функции является хорошим примером) приведет к проблемам производительности.

+0

возможно в setInterval() – coderex

+0

Да это possble и что это лучший способ сделать это – CMS

+0

@CMS: он работает спасибо :-) – coderex

1

первых, это '' SetTimeout

второй, не передать строку. Реальное решение зависит от остальной части кода. Наиболее надежным способом было бы улавливать область действия:

var obj_array = something; 
function trap(obj) 
{ 
    function exec() { foo(obj); } 
    return exec; 
} 
setTimeout(trap(obj_array), 1000); 

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

var obj_array = something; 
function trap() 
{ 
    function exec() { foo(obj_array); } 
    return exec; 
} 
setTimeout(trap(), 1000); 

или даже:

var obj_array = something; 
function trap() 
{ 
    foo(obj_array); 
} 
setTimeout(trap, 1000); 

и, наконец, конденсируется вниз:

var obj_array = something; 
setTimeout(function() { foo(object_array); }, 1000); 

EDIT : Мои функции (или, по крайней мере, одна итерация из них я нашел в резервной копии здесь)

Function.prototype.createDelegate = function(inst, args) { 
    var me = this; 
    var delegate = function() { me.apply(inst, arguments); } 
    return args ? delegate.createAutoDelegate.apply(delegate,args) : delegate; 
}; 
Function.prototype.createAutoDelegate = function() { 
    var args = arguments; 
var me = this; 
return function() { me.apply({}, args); } 
}; 

ДАЛИ:

function test(a, b) { alert(a + b); } 

Usage:

setTimeout(test.createAutoDelegate(1, 2), 1000); 

ИЛИ ДАЛИ:

var o = { a:1, go : function(b) { alert(b + this.a); }} 

ПРИМЕНЕНИЕ:

setTimeout(o.go.createDelegate(o,[5]), 1000); 
//or 
setTimeout(o.go.createDelegate(o).createAutoDelegate(5), 1000); 
2

Я собираюсь Expan d на ответ Луки здесь, потому что он рассматривает прецедент, что CMS (и большинство ответов на этот вопрос) не делает.

Если вам необходимо связать свои аргументы вызова функции в установленное время тайм-аута, простая функция корпус не будет работать:

echo = function (txt) { console.log(txt); }; 

val = "immediate A"; 
echo(val); 

val = "delayed"; 
window.setTimeout(function() { echo(val); }, 1000); 

val = "immediate B"; 
echo(val); 

Предполагая, что вы используете консоль Firebug, тем выше будет выведите «немедленный A», «немедленный B», а затем «немедленный B» через 1 секунду позже. Чтобы привязать значение во время вызова setTimeout, используйте метод ловушки Luke. Ниже изменяет его немного, чтобы принять произвольные функции и длину аргументов:

echo = function (txt) { console.log(txt); }; 

trap = function (fn, args) { 
    return function() { 
     return fn.apply(this, args); 
    }; 
}; 

val = "immediate A"; 
echo(val); 

val = "delayed"; 
window.setTimeout(trap(echo, [val]), 1000); 

val = "immediate B"; 
echo(val); 

Не уверены, что если есть способ, чтобы передать контекст вызывающего абонента в неявном, но она может быть расширена, чтобы принять контекст аргумент, если «это «Ты не туда попадешь.

+0

ваша версия ловушки та же идея моей createDelegate и функции trapScope. Добавлен в нижней части моего ответа для интереса –

+0

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

+0

'+ 1' этот ответ спас мой лоб от удара стены. Благодарю. – RASG