11521 sujets

JavaScript, DOM et API Web HTML5

Bonsoir

Je voudrais mettre dans un "objet" un setTimeout sur une méthode interne à l'objet, du genre:
MonObjet = function() {
    ........
    ........
    this.smurf= function() {
        ........
        ........
        setTimeout(this.smurf, 1000);    /* relancer la même méthode dans 1s */
    }
}

Cette syntaxe ne fonctionne pas, l'appel au bout d'une seconde se produit sur un objet vide.

Pour l'instant j'ai lancé le timer sur une fonction externe, qui relance l'appel, du genre:
var cetObjet = new MonObjet(...);
    ........
var relais = function() {
    cetObjet.smurf();
}

et dans la définition de "this.smurf": setTimeout(relais, 1000);

Quelqu'un aurait il une idée sur une façon plus propre de traiter ce problème?
Modifié par PapyJP (18 Dec 2015 - 18:13)
niuxe a écrit :
Salut,
Ton souci provient d'une méconnaissance du scope (portée d'une variable) et de la poo. Je t'invite à regarder en console ce que cela donne Smiley cligne

Merci de ta réponse
Ayant été (dans les années 1980) l'un des premiers à avoir introduit la programmation orientée objet dans le logiciel industriel (je veux dire en dehors de la recherche et des labos), je ne crois pas que ce soit le cas. Smiley cligne
Je comprends parfaitement POURQUOI ça ne marche pas. Je cherche simplement à savoir COMMENT FAIRE pour que ça marche sans faire appel à un relais.

Cela vient vraisemblablement de la façon dont JS traite la fonction setTimeout.
Au moment où ma méthode appelle setTimeout, on est bien dans un objet identifié, donc d'un point de vue sémantique "this.smurf" signifie bien "la méthode smurf de l'objet en cours", objet qui existe
Si on regarde dans les implémentations internes, un objet est une zone de mémoire contenant des pointeurs, propre à l'objet. Ce pointeur est parfaitement défini (car sinon la méthode ne serait pas appelée) Tout ce que je lui demande c'est de passer ce pointeur à la fonction setTimeout.
Ce que je cherche, c'est quelle est la bonne syntaxe pour lui passer cette information.
PapyJP a écrit :

Merci de ta réponse
Ayant été (dans les années 1980) l'un des premiers à avoir introduit la programmation orientée objet dans le logiciel industriel (je veux dire en dehors de la recherche et des labos), je ne crois pas que ce soit le cas. Smiley cligne

#punchline Smiley frappe
Smiley lol

Bref, bonjour,
Ça vient du fait que setTimeout appelle le code dans le contexte global, donc this représente window dans votre méthode.
Le plus simple, c'est de créer une variable qui pointe vers this avant d'appeler setTimeout, et d'utiliser une fonction anonyme qui fera l'appel à la méthode via cette variable.
var self=this;
setTimeout(function(){self.smurf();},1000);

ou encore, passer à la fonction anonyme le contexte d'exécution :
setTimeout(function(c){c.smurf();}, 1000, this);

ou enfin, si vous faites fi des anciens moteurs ne connaissant pas la méthode bind, utiliser cette méthode pour modifier le contexte d'exécution :
setTimeout((function(){this.smurf();}).bind(this), 1000);


Bonne journée
Seven tears a écrit :
Ça vient du fait que setTimeout appelle le code dans le contexte global, donc this représente window dans votre méthode.

C'est sûr, en fait tout se passe comme si ce qui était passé à setTimeout était une chaine de caractères à interpréter "this;surf" et non pas un pointeur vers la fonction "surf" de l'objet.
Seven tears a écrit :
Le plus simple, c'est de créer une variable qui pointe vers this avant d'appeler setTimeout, et d'utiliser une fonction anonyme qui fera l'appel à la méthode via cette variable.
[code=javascript]var self=this;

Je crois que ça doit être une bonne solution.
Pas le temps de tester cela ce matin, j'attends mon retour ce soir avec l'impatience et l'intérêt que mérite cette approche!
Modérateur
PapyJP a écrit :

Merci de ta réponse
....
Ayant été (dans les années 1980) l'un des premiers à avoir introduit la programmation orientée objet dans le logiciel industriel (je veux dire en dehors de la recherche et des labos), je ne crois pas que ce soit le cas.

Je comprends parfaitement POURQUOI ça ne marche pas. Smiley cligne

Smiley toilet Smiley bad
Smiley roi
Smiley frnuls

règle 11
règle 12

ps : Arf, Coluche et tes conneries...

Seven tears a écrit :

#punchline Smiley frappe
Smiley lol

Evite d'en rajouter s'il te plait. Tu mets de l'huile sur le feu....
Modifié par niuxe (20 Dec 2015 - 15:32)
PapyJP,

Si tu veux résoudre ce problème de manière élégante (et en apprenant pleins de choses trop cool) tu peux éventuellement passer ton script en ES6 et le compiler en JS. Ensuite utiliser des fonctions fléchées pour ce genre d'instruction.

Cela nécessite un peu de mise en place mais c'est très enrichissant au niveau de l'apprentissage. Et beaucoup moins casse tête sur certaines choses (comme ce cas-ci).

Bonne continuation Smiley smile