2009-08-14 11 views
4

Je souhaite passer un tableau d'objets à la fonction setTimer en Javascript.Comment passer un objet Array à la fonction setInterval

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

Je reçois une erreur sur ce code.

** Note: ** Désolé! une certaine correction dans ma question: Est-ce possible dans la fonction setInterval().

Répondre

17

Utilisez une fonction anonyme au lieu d'une chaîne sur le premier paramètre des fonctions setTimeout ou setInterval:

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

Pourquoi ça marche:

Lorsque vous définissez une fonction interne, il peut se référer aux variables présentes dans leur fonction englobante externe même après que leurs fonctions parentes aient déjà été terminées. Cette fonctionnalité est appelée closures.

Si vous passez une chaîne comme premier argument de ces fonctions, le code sera exécuté en interne au moyen d'un appel à la fonction eval, et le faire est pas considéré comme un good practice.

Eval permet d'accéder directement au compilateur JavaScript et exécute le code il est passé avec les privilèges de l'appelant, également à l'aide eval à plusieurs reprises/largement (à savoir votre fonction setInterval est un bon exemple) va conduire à des problèmes de performance.

+0

est-il possible dans setInterval() – coderex

+0

Oui, il est possble et c'est la meilleure façon de le faire – CMS

+0

@CMS: il fonctionne grâce :-) – coderex

1

d'abord, il est 'setTimeout'

En second lieu, ne passez pas une chaîne. La vraie solution dépend du reste du code. Façon la plus robuste serait de piéger la portée:

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

piège retourne une fonction qui a votre choix pris dans son champ d'application.Cette fonction est générique, mais pour le rendre spécifique à votre problème, il peut être simplifié:

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

ou même:

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

et enfin condensé jusqu'à:

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

EDIT : Mes fonctions (ou au moins 1 itération d'entre eux j'ai trouvé dans une sauvegarde ici)

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

DONNÉ:

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

USAGES:

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

OU DONNÉ:

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

USAGES:

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

Je vais EXPAN d sur la réponse de Luke ici parce qu'il traite d'un cas d'utilisation que CMS (et la plupart des réponses à ce genre de question) ne répond pas.

Si vous devez lier vos arguments à l'appel de la fonction au moment où vous définissez le délai, une enceinte simple fonction ne fonctionne pas:

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

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

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

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

En supposant que vous utilisez la console Firebug, la volonté ci-dessus sortie "immédiat A", "immédiat B" puis "immédiat B" 1 seconde plus tard. Pour lier la valeur au moment de l'appel setTimeout, utilisez la méthode d'interruption de Luke. Ce qui suit modifie un peu d'accepter des fonctions arbitraires et longueurs d'argument:

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

Je ne sais pas s'il y a un moyen de transmettre le contexte de l'appelant en implicitement, mais il pourrait être étendu à accepter un argument de contexte si « cette "Tu ne vas pas là-bas.

+0

votre version de piège est la même idée à mon createDelegate et les fonctions trapScope. Ajouté au bas de ma réponse pour l'intérêt –

+0

J'ai dû faire face à ce problème plusieurs fois dans le passé et toujours réglé pour les solutions de contournement de suivi d'état maladroit jusqu'à ce que j'ai vu votre solution. Presque tous les sujets que j'ai trouvé sur les délais et les intervalles parlaient de l'utilisation de boîtiers sans tenir compte des conditions de course. –

+0

'+ 1' cette réponse a sauvé mon front de frapper un mur. Merci. – RASG