Je voudrais savoir s'il est possible de passer par reference un argument en javascript . si oui comment procède t-on? Merci
Je voudrais savoir s'il est possible de passer par reference un argument en javascript . si oui comment procède t-on? Merci
Si je ne me trompe pas, les arguments en javascript sont tous passés en référence, hormis les types primitifs.
A confirmer.
Vrai. Les types primitifs en JS sont les nombres et les booléens. Tout le reste est objet donc passé par référence, ce qui inclut les chaînes, les tableaux, les fonctions, etc.
Exemple avec un objet littéral :
Certains sont tentés de déclarer toutes leurs variables avec new, y compris celles de type primitif, par exemple new Number(42). C'est une mauvaise idée, car en faisant ça on crée en fait un objet et les avantages du type primitif sont perdus.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 var obj = {}; function ajouterProp(o) { o.prop = "bonjour"; } ajouterProp(obj); // obj est automatiquement passé par référence console.log(o.prop); // affiche "bonjour" dans la console
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Les arguments d'une fonction en Javascript sont tous sans exception, c'est à dire quel que soit leur type objet ou pas, passés par valeur et non par référence.
La spécificité d'un passage par référence est que dans l'appelant, l'argument passé peut revenir modifié. On ne parle pas de son contenu, mais de l'argument lui même.
Quels que soient les types et valeurs pour a et b.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 // Soit une fonction qui échange ses arguments : function swap ( a, b ) { var t = a; a = b; b = t; } var a = 1, b = "deux"; swap(a,b); // Si a et b étaient passés par référence, on aurait // a == "deux" et b == 1 // mais ici, on aura toujours // a == 1 et b == "deux"
Je rejoins kaari & Watilin sur ce point pour ma part tout ce qui est objet sera passé par référence, tout ce qui est primitive sera par valeur.
Ton exemple lysandro, utilise deux primitives. Un Number & un String
Exemple avec un Objet :
C'est bien l'adresse de l'objet qui est passée.
je ne sais pas quel est le langage de préilection de lysandro
Mais je pense qu'il y a confusion sur le terme référence.
il existe 3 façon de passer une variable à une fonction.
Par valeur
Par référence
Par pointeur
Le passage par valeur est facile à comprendre.
La valeur est donnée à la fonction et celle-ci ne connait pas la variable. elle ne peut donc pas la modifier.
Le passage par référence conciste à donner une référence à la variable en parrametre à la fonction.
La fonction a donc connaissance de la variable et peut en modifier la valeur. mais elle ne peut pas modifier la variable elle même.
par exemple si je passe un objet User dont le nom est toto je peut modifier le non de User mais cela restera User.
Le passage par pointeur conciste à donner une référence sur l'adresse de la variable.
la fonction peut donc accéder à la valeur.
elle a aussi connaissance de la variable et peut modifier sa valeur
mais comme elle a une référence à l'adresse elle peut aussi modifier cette référence.
la chose se résume ainsi
soit deux varaible référençant le même objetAppel par valeur f(a); l'objet référencé par a et par b n'a pas changé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 +--------+ a ->| | | x:15 | b ->| | +--------+Appel par référence f(a); l'objet référencé par a et par b a pas changé mais a et b référence toujour cet objet
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 +--------+ a ->| | | x:15 | b ->| | +--------+Appel par pointf(a); l'objet référencé par a n'est plus le même que celui référencé par b.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 +--------+ a ->| | | x:32 | b ->| | +--------+En Javascript seuls les passage par valeur pour les type primitifs et par référence pour tout le reste existe.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 +--------+ a ->| x:32 | +--------+ +--------+ b ->| x:15 | +--------+
A+JYT
Les chaînes de caractères sont des primitives aussi !
http://msdn.microsoft.com/en-us/libr...(v=vs.94).aspx
https://developer.mozilla.org/fr/doc...e_donn%C3%A9es
Si on prend comme définition de primitive tout ce qui n'est pas objet, on a bien "string" instanceof Object === false.
Je pense que sekaijin a vu juste. Je pense que Kouamé josué veut savoir si on peut passer des arguments par référence à une fonction. Exemple en PHP :
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 $maVariable = 'coucou'; function changeCoucou(&$a) { $a = 'toto'; } changeCoucou($maVariable); // $maVariable vaut maintenant 'toto'
En JavaScript, il n'y a pas d'équivalent de l'opérateur & devant les paramètres d'une fonction.
J'ai ici pris 4, mais ça vaut pour toutes les primitives (voir ci-dessous la définition).
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 function changeX(x) { x = 5; // x ici est propre au contexte de la fonction changeX. C'est une variable locale à la fonction, accessible que à l'intérieur de cette fonction. } var x = 4; alert(x); // x vaut 4 changeX(x); alert(x); // x vaut toujours 4
Par contre, si tu passes un objet {} ou un array [] :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 function changeX(x) { x.push('toto'); // on insére 'toto' à la suite du tableau } var x = ['tata']; alert(x); // x vaut ['tata'] changeX(x); alert(x); // x vaut ['tata', 'toto']
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 function changeX(x) { x.propriete2 = 'toto'; // on ajoute la propriété 'propriete2' ayant pour valeur 'toto' à l'objet } var x = { propriete1: 'tata' }; alert(x); // x vaut {propriete1: 'tata'} changeX(x); alert(x); // x vaut {propriete1: 'tata', propriete2: 'toto'}
Y'a un peu plus de types primitifs en réalité (selon la spéc) :Vrai. Les types primitifs en JS sont les nombres et les booléens.
Undefined (undefined), Null (null), Boolean (true ou false), Number (42, 3.14, 1e6, NaN, Infinity, -Infinity ... ils suivent la norme IEEE 754), ou String ("coucou" ou 'coucou')
Merci Sylvain et Kaamo de me corriger, effectivement je me suis bien planté. Et je peux plus éditer mon message
Du coup je rajoute que si on manipule des chaînes longues, il faut garder à l'esprit qu'elles sont copiées lorsqu'on les passe à une fonction. Ça peut poser des problèmes de mémoire.
La FAQ JavaScript – Les cours JavaScript
Touche F12 = la console → l’outil indispensable pour développer en JavaScript !
Kaamo avec sa fonction 'changeCoucou()' donne un excellent exemple de passage par référence.
Dans son exemple, on voit bien que c'est '$maVariable' qui est modifiée. C'est impossible à faire en Javascript. Ca ne dépend pas du tout du type de '$maVariable' (enfin je l'espère, je ne connais pas PHP).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 $maVariable = 'coucou'; function changeCoucou(&$a) { $a = 'toto'; } changeCoucou($maVariable); // $maVariable vaut maintenant 'toto'
Le passage par pointeur n'existe pas. Un pointeur c'est un type de variable, ni plus ni moins.
La confusion vient de ce qu'on peut passer par valeur des types modifiables, par exemple un tableau.
Dans le cas de l'appel 'f(b)', on peut modifier le contenu du tableau, en ajoutant ou retirant des éléments. Mais impossible de le mettre à 'null' par exemple.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 function f ( x ) { // code utilisant x } var a = 1; var b = [1]; // à l'appel f(a) // f reçoit 1 <=> f(1) // à l'appel f(b) // f reçoit [1] <=> f([1])
C'est bien la valeur de 'b' qui est passée et non la variable 'b' elle-même.
Par contre, si on pouvait écrire comme en PHP
C'est un passage par référence. On peut modifier la variable 'b' (ou 'a'), pas seulement son contenu. C'est l'exemple de Kaamo.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 function f ( &x ) { // code utilisant x } var a = 1; var b = [1]; // à l'appel f(a) // f reçoit l'adresse mémoire de la variable a <=> f([abcd]) où [abcd] est l'adresse de a qui contient 1 // à l'appel f(b) // f reçoit l'adresse mémoire de la variable b <=> f([wxyz]) où [wxyz] est l'adresse de b qui contient le tableau [1]
On peut remarquer au passage que rien ne distingue les deux formes d'appels, par valeur ou par référence (aussi appelé par variable).
En ce qui concerne le passage de pointeurs, on aurait
C'est toujours un passage par valeur. Dans ce cas trés particulier, on pourrait modifier 'a' qui n'est même pas passé en argument mais toujours pas 'b'.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 function f ( x ) { // passage par valeur // code utilisant x } var a = 1; var *b = &a; // b est un pointeur qui contient l'adresse de a et *b == 1 // à l'appel f(a) // f reçoit 1 <=> f(1) // à l'appel f(b) // f reçoit [1] <=> f([wxyz]) où [wxyz] est l'adresse de b qui contient l'adresse de a:[abcd]
En espérant avoir éclairci ce que je voulais dire
encore une fois les variable sont passé par référence.
en fonction de leur type.
comment fonction un langage interprété
lorsque tu définie une variable tu ajoute une nouvelle entrée dans la table des symboles connu (une espèce de tableau associatif)
cette entrée contien deux chose un nom et une adresse (null est une adress comme une autre.)
à cette adresse ce trouve un contenu (objet, tableau, caractère, nombre, etc.)
Appeller une fonction avec un paramètre consiste à mettre le dit paramètre sur la pile d'éxécution
créer un contexte d'éxécution
puis à exécuter le corps de la fonction.
la premère chose que celle-ci fait c'est prendre le paramètre et définir dans la table des symboles de son contexte
une entrée qui contient le nom du paramètre et le contenu de ce qui est sur la pile d'éxéution.
soit la variable a = 15 (le symbole a est à l'adresse @100 dans la table des symbole et 15 à l'adresse @115)
on place sur la pile 15 (au sommet de la pile adresse @1005)
on créé un contexte
on définit un symbole param (dans le contexte param adresse @256 15 adresse @271)
param = 15
la fonction peut s'éxécuter.
ceci s'appelle un passage par valeur.
soit la variable a = {age:15} (le symbole a est à l'adresse @100 dans la table des symbole et {age:15} à l'adresse @115)
on place sur la pile {age:15} (au sommet de la pile adresse @1005)
on créé un contexte
on définit un symbole param (dans le contexte param adresse @256 {age:15} à l'adresse @115)
param = {age:15}
la fonction peut s'éxécuter.
ceci s'appelle un passage par référence. ce qui est placé sur la pile est @115
soit la variable a = {age:15} (le symbole a est à l'adresse @100 dans la table des symbole et {age:15} à l'adresse @115)
on place sur la pile a (au sommet de la pile adresse @1005)
on créé un contexte
on définit un symbole param (dans le contexte param adresse @256 a à l'adresse @100)
param = {age:15}
la fonction peut s'éxécuter.
ceci s'appelle un passage par pointeur. ce qui est placé sur la pile est @100
le passage par valeur consiste à passer en paramètre la valeur contenue à l'adresse référencé par la variable.
le passage par référence conciste à passer en paramètre l'adresse de l'objet référencé par la variable.
le passage par mointeur consiste à passer en paramètre l'adresse de la varriable pas ce qu'elle référence.
si tu avais fais un passage pas valeur tu auraisdans le cas d'une String
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 @100 @115 +-----+ +--------+ | a |--------->| 15 | +-----+ +--------+ @256 @271 +-----+ +--------+ |param|--------->| 15 | +-----+ +--------+
en javascript on ne mets pas 'Jhon Doe' sur la pile mais on pets bien @115
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 @100 @115 +-----+ +----------+ | a |--------->|'Jhon Doe'| +-----+ +----------+
lorsque tu arrive dans ta fonction tu est dans la situation suivantetu a bien un référence à 'Jhon Doe'
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 @100 @115 +-----+ +----------+ | a |---+----->|'Jhon Doe'| +-----+ | +----------+ @256 | +-----+ | |param|---+ +-----+
puis tu faisla variable param ne référence plus 'Jhon Doe' mais 'bill'
Code : Sélectionner tout - Visualiser dans une fenêtre à part param = 'bill';
c'est exactement ce que fais javascript
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 @100 @115 +-----+ +----------+ | a |--------->|'Jhon Doe'| +-----+ +----------+ @256 @915 +-----+ +--------+ |param|--------->| 'bill' | +-----+ +--------+
maintenant ce que ferait un passage par pointeurtu n'a plus de référence à l'objet référencé par a mais une référence à a lui-même.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 @256 @100 @115 +-----+ +-----+ +----------+ |param|--->| a |-------->|'Jhon Doe'| +-----+ +-----+ +----------+
en utilisant la syntaxe adapté qui n'existe pas en javascript tu pourais faire un truc du genrepour obtenir
Code : Sélectionner tout - Visualiser dans une fenêtre à part ¶m='bill';
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 @256 @100 @115 +-----+ +-----+ +------+ |param|--->| a |-------->|'bill'| +-----+ +-----+ +------+
en C/C++ tu crée une variable de type pointeur sur string
à l'éxécussion un mot mémoire est loué à l'adresse @100 qui représente ce pointeur
puis tu appelle une fonction qui alloue de la mémoire à l'adresse @248 et affecte cette adresse à ton pointeur.
tu quitte ta fonction et ta variable a pour valeur @248
tu crée une variable de type string
à l'éxécussion un mot mémoire est loué à l'adresse @100 qui représente ce pointeur
tu affecte à cette variable une string allouée à l'adresse @248
tu appelle une fonction en passant la variable par référence qui change le premier caractère en Majuscule.
tu quitte ta fonction. ta variable à le contenu de son premier caractère en majuscule
que c'est il passé dans le premier cas tu as mis @100 sur la pile qui est l'adresse du pointeur tu as bien passé le pointeur
dans le deuxième tu as mis @248 sur la pile qui est bien ce qui est référencé par ta variable.
avec un passage par valeur si ta variable contenait 'jhon doe' tu n'aurais pas mis @248 sur la pile mais 'jhon doe'
le compilateur C et suffisement sioux pour ne pas faire ça.
soit il ne peut y avoir de modif et il met @248 sachant que la fonction en modifira pas l'objet
soit il y a un risque et il copie 'jhon doe' dans une autre zone @1452 par exemple et place @1452 sur la pile.
mais ça c'est juste une optimisation.
lire la théorie de la compilation et de l'interprétation des langages informatique.
A+JYT
Ok, j'ai fait un contresens sur la question posée initalement, désolé.
Mais ça ne change rien :-) Il suffit de faire une recherche dans un moteur avec 'passage par référence'.
Maintenant, le fait que pour certains arguments ce soit l'adresse qui soit passée (sur une pile ou pas d'ailleurs) ne change pas le type du passage des arguments.
Je comprends que vous faites la différence entre passer une adresse ou le contenu, mais ce n'est pas ce qu'usuellement j'appelle un passage par référence ou par valeur.
Puisque vous évoquez le C/C++, le C n'a que du passage par valeur (bien qu'il puisse passer des adresses comme avec les pointeurs mais aussi les tableaux) alors que le C++ possède en plus un passage par référence.
De plus, le fait de passer une adresse ne rend en rien le contenu modifiable, cas des "string" (typeof) en Javascript dont c'est sans doute l'adresse qui est passée mais qui ne sont pas modifiables pour autant.
Mon erreur d'interprétation vient de ce que, dans un langage ne possédant qu'un passage par valeur, que l'on puisse passer l'adresse d'un objet ou son contenu n'a pas d'impact. Cela relève de l'implémentation. Ce qui relève du langage c'est est-ce que je peux modifier le contenu et que cette modification soit répercutée dans l'environnement de l'appelant. Ce qui était, je crois le sens de la question.
Il me semblait que sématiquement, il était important de distinguer des fonctions déclarées
(bien que & n'existe pas en Javascript, c'est juste un exemple)
de
Code : Sélectionner tout - Visualiser dans une fenêtre à part function f ( &x ) { ... };
car dans les deux cas l'appel s'écrit de la même façon, mais n'a pas le même sens.
Code : Sélectionner tout - Visualiser dans une fenêtre à part function f ( x ) { ... };
On est au niveau du langage. Savoir si c'est une adresse qui est passée ou pas est au niveau de l'implémentation. Par exemple, j'utilise Rhino comme moteur ES5, qui est écrit en Java, qui est transformé en bytecode pour la JVM sur une plateforme Windows. Comment mon argument Javascript est réellement passé à ma fonction ? je n'en sais rien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part f(a);
encore une fois je conseille de lire la théorie des langages
dans la théorie de langage
soit deux variable A, B qui référencent le même objet (string int tab etc. peu importe sa nature)
lors d'un passage par valeur de la variable A seul le contenu de la zone mémoire référencé par la variable est trans mis à la fonction
si la fonction modifie ce contenu qui lui a été passé
le contenu de la zone mémoire référencé par les variable A et B n'a pas changé.
lors d'un passage par référence de la variable A c'est la référence de la zone mémoire contenant les donnée qui est transmise. si la fonction modifie ce contenu qui lui a été passé
le contenu de la zone mémoire référencé par les variable A et B n'a a changé et on peut le vérifier en inspectant le contenu référencé par B
lors d'un passage par pointeur de la variable A c'est une référence à la zone mémoire contenant A et non pas la zone référencé par A qui est transmise.
si la fonction affecte un nouvel objet à son paramètre
Le contenu de la zone référencé par B n'a pas changé
Mais A référence une nouvelle zone.
Je crois que tu confonds la variable et l'objet référencé par la variable.
en C++ lorsque tu faisil n'y a rien en mémoire qui représente la variable A elle n'existe que dans le langage et le compilateur remplace le symbole A par l'offset de la zone allouée pour le char[5]
Code : Sélectionner tout - Visualiser dans une fenêtre à part char[5] A;
A référence une zone char[5] et seule cette zone existe en mémoire. (il est nécessaire de compiler avec des option de debug pour que le compilateur ajoute dans le codé généré une table d'association contenant le symbole A et l'offset de la zone char[5];
A et une variable char[5] l'objet qu'elle référence.
si tu fais si tu passe A par référence à une fonction tu passe l'offset associé à A le contenu de char[5] peut être modifié
mais A référence toujours la même zone mémoire.
pour pouvoir changer la zone que référence A il faut utiliser un pointeurcette fois le compilateur va créer deux zone un mot mémoire qui est le pointeur et une zone pour le char[5]
Code : Sélectionner tout - Visualiser dans une fenêtre à part char[5] *A;
lorsque tu passe la variable A tu passe l'offset de A cet a dire le mot mémoire. si tu change la valeur de ce mot ton point référencera une nouvelle zone char[5]
le passage par référence c'est comme si je te donnais les infos d'un ami contenu dans mon carnet d'adresse.
ces infos te permettent de retrouver mon ami et fêter avec lui son anniversaire.
tu aura donc changé les informations de notre ami.
mais mon carnet d'adresse continuera à le référencer. (I.E. les infos de mon carnet permettent de le retrouver)
ce l'est pas la même chose que de te donner la possibilité de changer le contenu de mon carnet d'adresse.
Je pense que ce qui te pose problème avec javascript c'est qu'e si tu modifie une string dans ta fonction la variable ne semble pas affecté.
en javascript les String son non modifiable. on peut créer d'autre string avec les opérateurs et les fonctions mais on ne modifie jamais une string.
Mais en fait tu ne modifie jamais une string toute les opération sur les strings créent une nouvelle string.
tu viens de créer 3 strings.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 a = 'test'; b = 'truc'; c = a + b;
la encore tu crée 3 strings (b et p seront détruite immédiatement mais elle sont tout de même créées.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 a='test'; function (p) { b = 'truc'; p = p + b; } f(a);
A+JYT
probablement par copie pour les types primitifs (ou const référence si on délègue l'instanciation de copie dans la fonction)
Code : Sélectionner tout - Visualiser dans une fenêtre à part Comment mon argument Javascript est réellement passé à ma fonction
par valeur pour les autres types si ces autres types sont des pointeurs
par référence si ces autres types sont des objets pleins.
edit: même pas const ref, à cause de string[2]='c' qui modifie la string
Miam miam (passage par référence)
Oooh (passage par valeur)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 void b ( int &score ) { score++; } b(ton_score);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 function b ( score ) { score++; } b(ton_score);![]()
mais ce n'est pas ça qu'il veux
il vaut faire ça;
il veut que la fonction désalloue la mémoire référencé par test, alloue une autre zone et que test référence la nouvelle valeur
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 void b ( char[] &score ) { score="abcd"; //on affecte une nouvelle valeur au paramètre } char[] test = "wxyz"; b(test); printf(fest);// abcd
il voudrait que ça fasse ça. sauf qu'en javascript les string sont inmutablece que visiblement il ne comprends pas c'est que lorsqu'il fait un passage par référence il se passe ça:
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void b ( char[] &score ) { score[0]='a'; //on change le contenu de la zone référencé par le paramètre score[1]='b'; score[2]='c'; score[3]='d'; } char[] test = "wxyz"; b(test); printf(fest);// abcdcar c'est exactement ce qu'il se passe en javascript. il affecte une nouvelle valeur à son paramètre et ne change pas le contenu de l'objet.
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 char[] a = "wxyz"; char[] b = "abcd"; char[] c = &a; //passage du paramètre c référence le tableau référencé par a //il veut que l'affectation suivante modifie a c = &b; //c référence maintenant le tableau référencé par b //il veux que a contienne abcd printf(a); //a n'a pas changé. il a simplement changé la référence de c mais il n'a touché à aucun contenu
ce qui est la s'écrit en js
A+JYT
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 var a = "wxyz"; var b = "abcd"; var c = a; //passage du paramètre c référence le tableau référencé par a //il veut que l'affectation suivante modifie a c = b; //c référence maintenant le tableau référencé par b //il veux que a contienne abcd mais a n'a jamais changé. console.log(a);
Tu passe l'adresse mémoire de ton_score dans la fonction et tu modifie le contenu de cette adresse, et comme en js les pointeurs n’existent pas, il n'y a pas d'équivalent.
Tu passe la valeur de la variable ton_score comme paramètre de ta fonction.Oooh (passage par valeur)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 function b ( score ) { score++; } b(ton_score);![]()
Les pointeurs n’existent pas dans javascript, pour palier à ça et passer en référence des types primitifs, il y a un nombre infini de solution. Faut comparer ce qui est comparable...
PS : en ce qui concerne les tableaux, en C la taille des array doivent être indiqués à la définition car à la compilation la zone mémoire est réservée pour ce même tableau (ce qui n'a rien à voir avec des constantes de compilations car celle-ci sont interprétées par le compilateur et remplacées par leurs valeurs respectives, en dur, dans le code machine, pas dans la zone mémoire allouée aux variables).
Lorsqu'on souhaite utiliser un tableau à taille dynamique on peut alors utiliser des listes, qui pour chaque item ajoute l'adresse de l'itération suivante de la liste (qui peut se trouver n'importe où ailleurs en zone mémoire).
Tout ça pour dire que comparer array en js et array en C (en terme d'adressage mémoire) n'a absolument aucun sens.
lorsqu'on défini un variable dans n'importe quel langage on défini deux chose
un symbole qui va permettre de manipuler l'élément qu'il représente
et une zone mémoire.
Dans le cas d'un entier en javascript tout comme en c cet entier est représenté en mémoire par un mot mémoire (32b ou 64b)
dans un langage compilé le symbole n'existe que lors de la compilation (or options de debug)
dans le cas de javascript il existe en mémoire une table associative qui contient le symbole, son type, et une référence au mot mémoire contenant la valeur.
Dans le cas d'une chaine en javascript tout comme en c la chaine est représenté en mémoire par une suite de mots mémoire terminé par un 0
en javascript la variable et présente dans la table des symboles. cette table contient le nom de la variable le type et l'adresse en mémoire de la chaine.
l'orsqu'on passe l'entier par référence on passe son adresse. on ne passe pas la valeur contenue à cette adresse.
en C si on a compilé avec les options de debug on a en mémoire une table des symboles exactement comme en javascript.
si la fonction modifie l'entier suite à un passage par référence la variable n'a pas changé d'adresse.
c'est exactement ce qu'il se passe avec javascript pour les chaines.
une chaine de caractères en javascript n'est pas modifiable.
l'orsqu'on passe la chaine par référence on passe son adresse. on ne passe pas la valeur contenue à cette adresse.
si la fonction alloue une autre zone mémoire pour créer une autre chaine
la variable n'a pas changé d'adresse.
quelque soit le langage un passage par référence ne permet pas de changer la référence mais seulement ce qui est contenu à l'endroit référencé.
et comme en javascript les strings (pas les variable référençant des strings) ne sont pas modifiables une fonction ne peut pas modifier le contenu d'une string.
il se trouve qu'en javascript les type primitifs nombre et boolean sont toujours passé par valeur.
pour optimiser l'espace et les traitements au lieu pour un entier d'avoir une entrée dans la table qui contient le nom de la variable son type et l'adresse du mot mémoire contenant l'entier
la table des symbole contient le nom de la variable son type et l'entier directement.
ainsi pour les types primitif on fait l'économie d'une référence (ce qui facilite la libération de la mémoire) mais surtout
l'appel de fonction se fait toujours de la même façon
on passe à la fonction ce qui se trouve dans la table de symbole.
si c'est un type primitf la table contient la valeur ce sera donc un passage par valeur.
si c'est un type complexe la table contient l'adresse de l'objet ce sera donc un passage par référence.
comparé à C/C++ cela limite grandement les possibilités.
Mais du coup pour l'interprète c'est du systématique ce qui implique moins d'analyse moins de traitement.
quoi qu'il arrive que ce soit en javascript ou en C/C++ jamais une fonction ne pourra modifier le contenu de la table des symbole au travers d'une simple affectation de valeur.
A+JYT
On ne se comprend pas.
C++
L'appel des deux fonctions f0 et f1 est le même mais le résultat est trés différent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 int deux = 2; // passage par valeur d'un entier void f0 ( int x ) { x = 2; } // passage par référence d'un entier void f1 ( int& x ) { x = 2; } // passage par valeur d'un pointeur sur un entier void f2 ( int *x ) { *x = 2; } // idem f2 void f3 ( int *x ) { x = &deux; } int main(int argc, char* argv[]) { int exitcode = 0; int a; a = 1; f0(a); // a == 1 a = 1; f1(a); // a == 2 a = 1; f2(&a); // a == 2 a = 1; f3(&a); // a == 1 return exitcode; }
L'appel de f1 et f2 est différent, mais le résultat est le même.
f3 n'est là que pour montrer que passer même un pointeur par valeur n'est pas la même chose qu'un passage par référence.
Le fait de passer une adresse où pas ne transforme pas un passage par valeur en passage par référence. Les sémantiques des appels sont différentes.
En Javascript, indépendamment du type de l'élément passé, le modèle s'apparente plus à un passage par valeur où certains types de données seraient des pointeurs (string, Object) que de celui d'un passage par référence permettant d'écrire une fonction comme f1.
Donc, à la question initialement posée :
la réponse est non. Le langage ne permet pas de spécifier ce type de passage.Je voudrais savoir s'il est possible de passer par reference un argument en javascript ?
Maintenant, si vous posez la question :
est-ce que certains types de données sont passés par référence ?
la réponse peut-être oui, même si je considère que c'est plus un passage de pointeur par valeur.
Partager