Quiero pasar una matriz de objetos a la función setTimer en Javascript.

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

Recibo un error en este código.

** Nota: ** ¡Lo siento! alguna corrección en mi pregunta: ¿Es posible en la función setInterval ().

4
coderex 14 ago. 2009 a las 09:06

3 respuestas

La mejor respuesta

Utilice una función anónima en lugar de una cadena en el primer parámetro de setTimeout o < Funciones href = "https://developer.mozilla.org/en/DOM/window.setInterval" rel = "noreferrer"> setInterval :

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

Por qué funciona:

Cuando define una función interna, puede hacer referencia a las variables presentes en su función de cerramiento externo incluso después de que sus funciones principales ya hayan terminado.

Esta función de idioma se denomina cierres.

Si pasa una cadena como primer argumento de estas funciones, el código se ejecutará internamente mediante una llamada a eval, y hacer esto es no considerado como buenas prácticas.

Eval proporciona acceso directo al compilador de JavaScript y ejecuta el código que se pasa con los privilegios de la persona que llama, también usando eval repetidamente / extensamente (es decir, su función setInterval es un buen ejemplo) conducirá a problemas de rendimiento.

17
CMS 14 ago. 2009 a las 05:32

Primero, es 'setTimeout'

Segundo, no pase una cadena. La solución real depende del resto del código. La forma más sólida sería atrapar el alcance:

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

Trap devuelve una función que tiene su matriz atrapada en su alcance. Esta es una función genérica, pero para simplificarla a su problema, se puede simplificar:

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

O incluso:

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

Y finalmente condensado a:

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

EDITAR: Mis funciones (o al menos 1 iteración de ellas que encontré en una copia de seguridad aquí)

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); }
};

DADA:

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

USO:

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

O dada:

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

USO:

setTimeout(o.go.createDelegate(o,[5]), 1000);
//or
setTimeout(o.go.createDelegate(o).createAutoDelegate(5), 1000);
1
Luke Schafer 11 abr. 2010 a las 23:27

Voy a ampliar la respuesta de Luke aquí porque aborda un caso de uso que los CMS (y la mayoría de las respuestas a este tipo de preguntas) no abordan.

Si necesita vincular sus argumentos a la llamada a la función en el momento en que establece el tiempo de espera , una caja de función simple no funcionará:

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

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

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

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

Suponiendo que está utilizando la consola de Firebug, lo anterior mostrará "inmediato A", "inmediato B" y luego "inmediato B" 1 segundo después. Para vincular el valor en el momento de la llamada setTimeout, use el método de trampa de Luke. Lo siguiente lo modifica un poco para aceptar funciones arbitrarias y longitudes de argumento:

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

No estoy seguro de si hay una manera de pasar implícitamente el contexto de la persona que llama, pero podría ampliarse aún más para aceptar un argumento de contexto si "esto" no lo lleva allí.

2
Gin Doe 10 abr. 2010 a las 18:16