61 votes

Affectation de pointeur de fonction en Javascript

Considérez ce code javascript :

var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();

Lors de l'exécution de ce code, j'obtiens "A". Ce comportement fait-il partie de la spécification de javascript et est-ce que je peux m'y fier ?

70voto

siingCoder Points 281

Dans d'autres exemples, rien n'a été passé par valeur; tout a été passé par référence.

bar et foo sont TOUS DEUX des pointeurs

Toutes les variables/références vers des objets NON primitifs en javascript sont des pointeurs; les pointeurs sont natifs à javascript, ils sont par défaut.

var bar = function () { alert("A"); } //bar est un pointeur vers function1
var foo = bar;  //pointeur copié; foo est maintenant aussi un pointeur vers function1
bar = function () { alert("B"); };  //bar pointe vers function2
foo();  //foo est toujours un pointeur vers function1

Vous rencontrerez des erreurs et des bugs cachés si vous pensez qu'il s'agit de copies. Surtout si vous travaillez avec des objets complexes. Par exemple

function person(name){this.name = name}
var john = new person("john")
var backup = john
backup.name //john
john.name = "jack"
backup.name //jack, PAS john

Pour COPIER réellement un non primitif en javascript nécessite plus de travail que simplement a = b. Par exemple:

function person(name){  this.name = name}
var john = new person("john")
var backup = new Object()
backup = JSON.parse(JSON.stringify(john))
backup.__proto__ = john.__proto__   //utile dans certains cas
john.name = "jack"
backup.name //john

3 votes

Merci d'avoir éclairci cela, j'étais confus(e) en cherchant sur Internet si les "fonctions" étaient primitives alors qu'on m'avait dit que ce n'était pas le cas.

2 votes

Cette réponse devrait servir de preuve de pourquoi nous devrions apprendre davantage l'informatique et moins la programmation...

0 votes

Cette réponse est complètement fausse. Je sais que c'est vieux mais clairement les gens continuent de tomber là-dedans. JavaScript N'A PAS du tout de concept de pointeurs. JavaScript utilise des références, qui sont clairement différents des pointeurs.

39voto

cletus Points 276888

Oui, c'est attendu et fait exprès.

Votre question est en fait : est-ce que foo fait référence à bar comme le ferait une pointeur ou une référence dans un autre langage ?

La réponse est non : la valeur de bar au moment de l'assignation est assignée à foo.

1 votes

Pourquoi une copie de la valeur est passée lorsque les fonctions ne sont pas de types primitifs ?

6 votes

Juste pour clarifier la dernière phrase de cette réponse, rappelez-vous que la 'valeur de bar' est un 'pointeur vers la fonction', pas la fonction elle-même. Donc, après foo = bar, foo reçoit une copie - par valeur - de ce pointeur, ainsi foo et bar pointent vers l'objet de fonction autonome.

21voto

Bob Points 4773

Je suis un peu en retard ici mais j'ai pensé donner quand même une réponse et élaborer quelque chose.

Il vaut mieux ne pas penser en termes de pointeurs et de références mémoire lorsqu'on discute des détails internes de JavaScript (ou ECMAScript) en traitant avec les spécifications. Les variables sont des enregistrements d'environnement internes et sont stockées et référencées par nom, pas par adresse mémoire. Ce que fait votre instruction d'assignation, internement et par conception, c'est rechercher le nom de l'enregistrement d'environnement (soit "foo" soit "bar") et assigner la valeur à cet enregistrement.

Ainsi,

var bar = function () { alert("A"); }

assigne à l'enregistrement d'environnement "bar" la valeur (fonction anonyme).

var foo = bar;

appelle internement GetValue("bar") qui récupère la valeur associée à l'enregistrement "bar" et associe ensuite cette valeur à l'enregistrement "foo". Ainsi, après cela, la valeur d'origine de bar peut toujours être utilisée car elle est maintenant associée à foo.

Parce que JavaScript fait référence par chaîne et non par adresse mémoire, c'est précisément pourquoi vous pouvez faire des choses comme ceci :

someObject["someProperty"]

qui recherche la valeur en fonction du nom de la propriété.

5voto

polygenelubricants Points 136838

Oui, il n'y a rien de spécial dans le fait que les variables font référence à des fonctions, il n'y a pas d'aliasing impliqué.

var bar = 1;
var foo = bar;
bar = "quelque chose de totalement différent";
// foo est toujours 1

3voto

Amarghosh Points 33957

Oui, c'est le comportement correct.

//créer une variable bar et lui assigner une fonction
var bar = function () { alert("A"); }
//assigner la valeur de bar à la nouvelle variable foo
var foo = bar;
//assigner une nouvelle fonction à la variable bar
//puisque foo et bar ne sont pas des pointeurs, la valeur de foo ne change pas
bar = function () { alert("B"); };
//appeler la fonction stockée dans foo
foo();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X