injection de contexte dans une invocation de fonction JS

11 views
Skip to first unread message

Julien Wajsberg

unread,
Sep 7, 2010, 9:42:03 AM9/7/10
to webd...@googlegroups.com
Bonjour bonjour,

dans une fonction, j'aimerais réussir à exécuter une autre fonction en
ajoutant à son scope des variables que j'aurais définies.

je m'explique avec un cas concret.

Prenons le code suivant :

function doSomething() {
log("doSomething");
}

function callDoSomething() {
function log(str) {
var elt = document.getElementById('log');
elt.innerHTML += "<div>" + str + "</div>";
};

doSomething();
}

Le problème ici, c'est que dans "doSomething", la fonction "log"
n'existe pas. Elle n'est pas dans son scope. J'aimerais un moyen pour
l'injecter.

Le plus proche de ce que je veux que j'arrive à faire, ce serait ça :

function doSomething(ctxt) {
ctxt.log("doSomething");
}

function callDoSomething() {
function log(str) {
var elt = document.getElementById('log');
elt.innerHTML += "<div>" + str + "</div>";
};

doSomething({log: log});
}

Eventuellement, on peut rajouter un bloc "with(ctxt)" au début de
doSomething. Mais j'aimerais justement en quelque sorte qu'il soit
implicite.

Pour contextualiser, mon but final, c'est un code un peu plus
compliqué pour faire un système de plugins. Pour des raisons de
paranoïa aigüe (et peut-être parce que je suis infecté par Java), je
ne veux pas que ces fonctions "injectées" soient publiques.

Avez-vous une meilleure idée que ce que j'ai là ?

--
Julien

samuel

unread,
Sep 7, 2010, 9:46:49 AM9/7/10
to webd...@googlegroups.com
Salut,
je ne suis pas sûr de d'avoir saisi le but de la manœuvre.
Dans ton exemple où est le code du plugin et où est celui du core ?


--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Professionnels francophones du développement web.
Pour envoyer un message à ce groupe, adressez un e-mail à webd...@googlegroups.com.
Pour vous désabonner de ce groupe, envoyez un e-mail à l'adresse webdevfr+u...@googlegroups.com.
Pour plus d'options, consultez la page de ce groupe : http://groups.google.com/group/webdevfr?hl=fr


Julien Wajsberg

unread,
Sep 7, 2010, 9:49:56 AM9/7/10
to webd...@googlegroups.com
"doSomething" est une fonction du plugin; "callDoSomething" est dans
le core, ainsi que "log".

2010/9/7 samuel <zoul...@gmail.com>:

Thomas ZILLIOX

unread,
Sep 7, 2010, 9:57:57 AM9/7/10
to webd...@googlegroups.com
Bonjour à tous !

As-tu pensé à utiliser "prototype" pour ajouter la méthode "doSomething" au contexte du core ?

Bon après-midi,
Thomas.

Julien Wajsberg

unread,
Sep 7, 2010, 10:01:24 AM9/7/10
to webd...@googlegroups.com
2010/9/7 Thomas ZILLIOX <tho...@zilliox.me>:

> Bonjour à tous !
>
> As-tu pensé à utiliser "prototype" pour ajouter la méthode "doSomething" au
> contexte du core ?

ça ne fonctionne pas car doSomething n'aurait toujours pas accès aux
méthodes privées.

Vincent Voyer

unread,
Sep 7, 2010, 10:03:00 AM9/7/10
to webd...@googlegroups.com
Hello, je ne sais pas si la syntaxe te va par rapport à ton projet mais tu pourrais faire :

function doSomething() {
// this === callDoSomething
// log exists
    log('bla');
}

callDoSomething = {
 log : function(str) {
    alert(str);
 },
 init : doSomething
}

callDoSomething.init();

D'ailleurs tu peux carrément toujours coder de cette façon, avec des objets javascripts simples que tu peux appeler facilement grâce aux espaces de noms (CallDoSomething.xx).

Le 7 septembre 2010 15:42, Julien Wajsberg <fel...@gmail.com> a écrit :
--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Professionnels francophones du développement web.
Pour envoyer un message à ce groupe, adressez un e-mail à webd...@googlegroups.com.
Pour vous désabonner de ce groupe, envoyez un e-mail à l'adresse webdevfr+u...@googlegroups.com.
Pour plus d'options, consultez la page de ce groupe : http://groups.google.com/group/webdevfr?hl=fr




--
Vincent Voyer
http://zeroload.net
(+33)6 13 92 69 96
skype : v.voyer
http://twitter.com/zeroload

Réduisez le temps de chargement, gagnez de nouveaux clients

Julien Wajsberg

unread,
Sep 7, 2010, 10:07:50 AM9/7/10
to webd...@googlegroups.com
2010/9/7 Vincent Voyer <vin...@zeroload.net>:

> Hello, je ne sais pas si la syntaxe te va par rapport à ton projet mais tu
> pourrais faire :
>
> function doSomething() {
> // this === callDoSomething
> // log exists
>     log('bla');
> }

non, ça ça marchera pas.
Il faut que tu fasses calldoSomething.log.


> callDoSomething = {
>  log : function(str) {
>     alert(str);
>  },
>  init : doSomething
> }
>
> callDoSomething.init();
>
> D'ailleurs tu peux carrément toujours coder de cette façon, avec des objets
> javascripts simples que tu peux appeler facilement grâce aux espaces de noms
> (CallDoSomething.xx).

Ouaip, j'ai volontairement simplifié ici le code :-)

C'est pour ça que je vous ai aussi parlé des plugins : j'ai déjà une
classe, et je veux qu'elle puisse exécuter des fonctions extérieures
tout en leur donnant des méthodes privées.

Honnêtement, je pense pas qu'il y ait de solution. Il faudrait ajouter
une nouvelle "scope chain" (cf
http://www.jibbering.com/faq/notes/closures/#clScCh) à notre appel de
la fonction, mais je ne crois pas ce que soit possible.

--
Julien

samuel

unread,
Sep 7, 2010, 10:11:57 AM9/7/10
to webd...@googlegroups.com
Tu peux aussi faire un objet global qui contient toutes les méthodes accessibles au plugins, du genre :

API = {/*tout ce qui accesssible */}

doSomething(){
 API.log('truc much');
}

Dans tout les cas le contenu de la méthode log sera visible si le développeur du plugin fait une méthode du type :

function doSomething() {
 alert(log);
}

Logiquement il n'y a pas de voies pour partager des méthodes privées, et qu'elles restent privées : à partir du moment ou tu arrives à les partager elles ne sont plus privées

Julien Wajsberg

unread,
Sep 7, 2010, 10:29:00 AM9/7/10
to webd...@googlegroups.com
2010/9/7 samuel <zoul...@gmail.com>:

> Tu peux aussi faire un objet global qui contient toutes les méthodes
> accessibles au plugins, du genre :
> API = {/*tout ce qui accesssible */}
> doSomething(){
>  API.log('truc much');
> }

Ça rejoint mon passage de contexte en argument.
(et si on utilise apply ou call, on l'aurait avec this)

Le passage en argument ou par apply permet de mieux encapsuler la
chose, mais c'est similaire.

>
> Dans tout les cas le contenu de la méthode log sera visible si le
> développeur du plugin fait une méthode du type :
> function doSomething() {
>  alert(log);
> }

Ah ben oui.
Je veux juste éviter que n'importe quel autre bout de code puisse y
accéder par souci de propreté et d'élégance de code.

> Logiquement il n'y a pas de voies pour partager des méthodes privées, et
> qu'elles restent privées : à partir du moment ou tu arrives à les partager
> elles ne sont plus privées

certes, c'est du bon sens :-)

--
Julien

Olivier G.

unread,
Sep 7, 2010, 10:37:31 AM9/7/10
to webd...@googlegroups.com
Le 07/09/2010 15:42, Julien Wajsberg a �crit :

Pour contextualiser, mon but final, c'est un code un peu plus
> compliqu� pour faire un syst�me de plugins. Pour des raisons de
> parano�a aig�e (et peut-�tre parce que je suis infect� par Java), je
> ne veux pas que ces fonctions "inject�es" soient publiques.
>
> Avez-vous une meilleure id�e que ce que j'ai l� ?

Tu as regard� du c�t� des plugins jQuery ?
http://www.jquery.info/spip.php?article24

--
Olivier G.
http://twitter.com/lespacedunmatin
http://www.lespacedunmatin.info/


Julien Wajsberg

unread,
Sep 7, 2010, 10:40:30 AM9/7/10
to webd...@googlegroups.com
2010/9/7 Olivier G. <olivier...@gmail.com>:

> Le 07/09/2010 15:42, Julien Wajsberg a écrit :
>  Pour contextualiser, mon but final, c'est un code un peu plus
>>
>> compliqué pour faire un système de plugins. Pour des raisons de
>> paranoïa aigüe (et peut-être parce que je suis infecté par Java), je
>> ne veux pas que ces fonctions "injectées" soient publiques.
>>
>> Avez-vous une meilleure idée que ce que j'ai là ?
>
> Tu as regardé du côté des plugins jQuery ?
> http://www.jquery.info/spip.php?article24

oui oui,

dans les plugins jQuery, tout est public, c'est facile :-)

samuel

unread,
Sep 7, 2010, 11:12:37 AM9/7/10
to webd...@googlegroups.com
Je n'avais pas compris que seule le méthode dosomething pouvait accéder à log, dsl :)

est ce que tu as regardé du coté de l'héritage ?
Il y a peut être une solution de ce coté

Julien

samuel

unread,
Sep 7, 2010, 11:16:15 AM9/7/10
to webd...@googlegroups.com
je ne sais pas si cela peut t'aider mais ce code marche :

plugin = {dosomething : function(){
    this.log("trucmuch");
}};

core = {
    log : function(str){
        alert(str);
    },
    plug : {},
    register : function(o){
        this.plug = o;
        this.plug.log = this.log;
    },
    exec : function(){
        this.plug.dosomething();
    }
}


core.register(plugin);
core.exec();

Julien Wajsberg

unread,
Sep 7, 2010, 11:35:21 AM9/7/10
to webd...@googlegroups.com
Mouais, AMHA, autant utiliser apply pour faire ça :

this.plug.doSomething.apply(this).
Mais plus simplement, dans ton exemple, on pourrait directement
utiliser core.log :)

Bref, je vais rester avec ma variable contexte bien explicite ;)

2010/9/7 samuel <zoul...@gmail.com>:

Thomas Parisot // Oncle Tom

unread,
Sep 7, 2010, 2:07:42 PM9/7/10
to webd...@googlegroups.com
C'est ce que j'allais dire : call/apply.
C'est fait exactement pour ça.

2010/9/7 Julien Wajsberg <fel...@gmail.com>



--
Thomas PARISOT
Consultant Web, accessibilité et respect des standards
http://case.oncle-tom.net/
http://twitter.com/oncletom
Mobile : +336 08 40 35 49
Reply all
Reply to author
Forward
0 new messages