Как передать объект Array в функцию setInterval
-
16-09-2019 - |
Вопрос
Я хочу передать массив объектов в функцию setTimer в Javascript.
setTimer("foo(object_array)",1000);
получаю ошибку в этом коде.
**Примечание:**Извините!небольшая поправка в моем вопросе:Возможно ли это в функции setInterval().
Решение
Используйте анонимную функцию вместо строки в первом параметре setTimeout или setInterval функции:
// assuming that object_array is available on this scope
setInterval(function () { foo(object_array); }, 1000);
Почему это работает:
Когда вы определяете внутреннюю функцию, она может ссылаться на переменные, присутствующие в их внешней функции, даже после того, как их родительские функции уже прекращены.
Эта языковая особенность называется закрытия.
Если вы передадите строку в качестве первого аргумента этих функций, код будет выполнен внутренне с использованием вызова метода оценивать функция, и выполнение этого нет рассматривается как хорошая практика.
Eval обеспечивает прямой доступ к компилятору JavaScript и выполняет переданный им код с привилегиями вызывающей стороны, также используя eval. неоднократно/широко (т.е.ваша функция setInterval является хорошим примером) приведет к проблемам с производительностью.
Другие советы
Я собираюсь расширить здесь ответ Люка, потому что он касается случая использования, которого нет в 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», а затем через 1 секунду «немедленно B».Чтобы привязать значение во время вызова setTimeout, используйте метод ловушки Люка.Следующее немного модифицирует его, чтобы он мог принимать произвольные функции и длину аргументов:
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);
Не уверен, что есть способ неявно передать контекст вызывающего абонента, но его можно расширить, чтобы принять аргумент контекста, если «это» не приведет вас туда.
во-первых, это «setTimeout»
во-вторых, не передавайте строку.Реальное решение зависит от остальной части кода.Самым надежным способом было бы захватить область видимости:
var obj_array = something;
function trap(obj)
{
function exec() { foo(obj); }
return exec;
}
setTimeout(trap(obj_array), 1000);
ловушка возвращает функцию, в область действия которой попал ваш массив.Это общая функция, но чтобы приспособить ее к вашей проблеме, ее можно упростить:
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);
РЕДАКТИРОВАТЬ:Мои функции (или, по крайней мере, одна их итерация, которую я нашел здесь в резервной копии)
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); }
ИСПОЛЬЗОВАНИЕ:
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);