IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Passage d'argument à une fonction


Sujet :

JavaScript

  1. #21
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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.
    si tu lis la spec, tu as tout un barda notamment sur les references.
    toutes les variables sont des références.

    Quand tu passes une variable à une fonction, tu lui passes une référence.
    Donc si tu veux, à l'implémentation du moteur js, le passage se fait par valeur mais au final tu passes quand même une référence (fonctionnellement parlant).
    Le si tu veux, il est important, car rien ne t'interdis de passer une référence (au sens pointeur) si ca te plait. C'est un détail technique.

    La question plus intéressante car j'imagine que tout le monde sait que les objets sont ... des ref, et qu'ils seront modifiés au sein de la fonction c'est la gestion des types primitifs.

    à savoir:
    someFunc('test')
    il y aura-t-il création d'une ref pointant vers 'test' où bien une copie pure et dure de 'test'.
    Tout laisse supposer le premier cas, mais pour y répondre, il faut bouffer du v8 (ou ses camarades)

  2. #22
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Citation Envoyé par lysandro Voir le message
    On ne se comprend pas.

    C++
    Code C++ : 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;
    }
    ...
    On se comprends très bien sur le passage par référence
    ce que tu comprends pas ces que tu ne change pas l'emplacement en mémoire de ton entier

    en javascript l'entier est passé par valeur on ne peux pas le passer par référence.
    en C++
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int deux = 2;
    // passage par référence d'un entier
    void f1 ( int& x ) {
    	x = 2;
    }
    ton entier deux est à un emplacement mémoire par exemple @256
    tu appelle ta fonction en passant la référence.
    ta fonction va modifier la valeur ce trouvant dans la case @256
    deux n'a pas changé de place en mémoire il est toujours à l'emplacement @256

    lorsque tu fais
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    String maChaine = new String("test");
    // passage par référence d'une String
    void f1 ( String& x ) {
    	x = new String("toto");
    }
    tout comme pour ton entier maChaine est à un emplacement mémoire par exemple @2678
    tu appelle ta fonction en passant la référence.
    ta fonction peut modifier la valeur ce trouvant dans la case @2678
    mais le corps de la fonction affecte une nouvelle chaine @9845 à x elle ne modifie pas la valeur contenu à l'adresse @2678
    maChaine n'a pas changé de place en mémoire

    avant l'appel on a les symboles suivant
    maChaine -> @2678 'test'
    appel de la fonction avant l'instruction on a les symboles
    maChaine -> @2678 'test'
    x -> @2678 'test'
    on exécute le corps de la fonction on a
    maChaine -> @2678 'test'
    x -> @9845 'toto
    on quitte a fonction le symbole x n'existe plus
    maChaine -> @2678 'test'
    ma Chaine n'a pas changé.

    c'est simplement parce que dans le corps de ta fonction tu affecte une nouvelle référence au paramètre tu ne modifie pas le contenu référencé.
    tu as donc bien passé ta variable par référence mais tu n'a pas comme pour ton entier changé son contenu.

    de puis le début tu attends un effet que tu n'obtiens pas non pas parce que les variable sont passé par valeur mais parce que le corps de ta fonction ne fait pas ce que tu veux.
    en C++

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Person salaryMan = new String("jhon", 35);
    // passage par référence d'un objet Person
    void birthday ( Person& x ) {
    	x.age++;
    }
     
    // passage par référence d'un objet Person
    void replace ( Person& x ) {
    	x = new Person("thom", 25);
    }
    Dans les deux cas tu passe la variable par référence.
    après l'appel de birthday salaryMan a un an de plus
    après l'appel de replace salaryMan n'a pas changé

    en javascript
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    salaryMan ={nom:"jhon", age:35};
    // passage par référence d'un objet Person
    void birthday ( x ) {
    	x.age++;
    }
     
    // passage par référence d'un objet Person
    void replace ( x ) {
    	x = {nom:"thom", age:25};
    }
    Dans les deux cas tu passe la variable par référence.
    après l'appel de birthday salaryMan a un an de plus
    après l'appel de replace salaryMan n'a pas changé

    ce que tu fais avec ta string c'est la fonction replace qui n'a aucune chance de modifier la variable.
    tu ne changera jamais l'adresse référencé par une variable dans une fonction si tu passe le paramètre par référence.
    tu ne peux que modifier ce qui est contenu à l'adresse qu'on te donne.

    si je te dis prends mon cahier et sur la 4 page 3 ligne tu as le texte de l'exercice.
    tu te rends à cette page et tu lit le texte et tu note sur ton brouillon
    et tu notes page 4 ligne 3
    puis tu efface cette référence et tu écris page 25 ligne 32
    je reprends le cahier lorsque tu a fini et je constate qu'a la page 4 ligne 3 rien n'a changé.

    pourtant je ne t'ai pas donné le texte mais un référence pour le trouver.
    si tu avais modifié le texte à la ligne 3 page 4 j'aurais vu la modification.

    Ce n'est pas un problème de passage par référence c'est un problème d'affectation de référence.
    dans la fonction tu pense affecter une valeur string à la variable mais en fait tu affecte une nouvelle référence.

    A+JYT
    PS sorry pour les erreur de syntaxe C++ il y a longtemps que je n'ai pratiqué.

  3. #23
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Citation Envoyé par galerien69 Voir le message
    à savoir:
    someFunc('test')
    il y aura-t-il création d'une ref pointant vers 'test' où bien une copie pure et dure de 'test'.
    Tout laisse supposer le premier cas, mais pour y répondre, il faut bouffer du v8 (ou ses camarades)
    il y a création d'une référence.
    mais de toute façon la fonction ne peux pas modifier la string les String son inmutable.

    en javascript pour tout les type primitif a reçoit la valeur référencé par b
    pour tout les autre type a reçoit la référence à l'objet référencé par a
    ceci est vrai dans toute les affectations
    le passage de paramètre n'est rien d'autre qu'une affectation a un paramètre.

    A+JYT

  4. #24
    Invité
    Invité(e)
    Par défaut
    il y a création d'une référence.
    mais de toute façon la fonction ne peux pas modifier la string les String son inmutable.
    je vois pas ce qui te permet d'assurer qu'il y a création de référence dans ce cas précis.
    on peut très bien imaginer que la référence est créée pour un primitif dès qu'on essaie de l'assigner à une variable.

    idem elle n'est pas forcément crée si dans la fonction on ne s'en sert pas.
    Un cas peu probable, pas très productif, mais un cas quand même!

  5. #25
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    non en javascript les type primitif ne sont jamais traité par référence il le sont par valeur

    et pour les type complexe il sont toujours traité par référence.
    peut importe la définition de la fonction en javascript ce n'est pas la signature de la fonction qui détermine le fonctionnement d'un appel.
    c'est le moteur javascript
    lorsque tu appelles une fonction en passant un string
    une référence à cette chaine est placée dans la liste des arguments et cela même si dans la définition il n'y a pas d'argument
    c'est un peut comme si toute les définition de fonction avaient une signature java comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object f(Object... args) {
    }
    Donc quoi qu'il arrive lorsque tu fais l'interprète mets 'toto" quelque part dans la mémoire puis il ajout l'adresse de cette String dans la liste args.

    pour les types primitifs
    les valeur sont directement stockés dans la table des symboles (on a à faire à un interprète, il faut la conserver en mémoire)
    un appel de fonction consiste à créer un contexte d'exécution.
    relier celui-ci au contexte qui fait l'appel (porté des variable en js)
    ajouter le symbole args à ce contexte
    placer dans args toutes les valeurs des types primitifs passés dans l'appel
    placer dans args toutes les références des types complexes passé dans l'appel
    définir un symbole correspondant à chaque nom d'argument de la définition de la fonction dans le contexte
    relier chaque symbole à l'argument correspondant (par valeur pour les primitif, par référence pour les autres)
    commencer l'exécution du corps de la fonction.

    ce mécanisme est systématique il n'y aucun dérogation. le passage des arguments dans args ne dépends que de l'appel
    la création des symboles ne dépends que de la définition de la fonction.
    l'association des deux ne dépends que de leur présence dans le contexte.

    il s'agit donc à chaque fois de parcourir une liste (d'élément passé dans l'appel pour args, de symbole dans la signature pour les nom de paramètre, des symbole dans le contexte pour l'association)

    pas de dérogation pas de condition. un traitement simple prédéfini systématique.
    ce qui est couteux ceux sont les choix. un traitement conditionnel est toujours beaucoup plus couteux qu'un traitement systématique.

    En C++ le compilateur va déterminer la façon dont seront passé les arguments. il n'en connait que deux par valeur et par référence. pour le passage par référence et le passage par valeur des int float et boolean il produit une séquence qui est toujours la même. ce code généré consiste à placer le contenu d'un cellule mémoire sur la pile d'exécution. (le args de javascript).
    le passage par valeur des types complexes demande au compilateur plus de travail. il faut qui détermine si le contenu doit être copié ou s'il peut se permettre d'optimiser est passer une référence. une fois ce choix fait il produit soit un code qui copie dans le tas la valeur du type complexe et il utilise cette référence soit il utilise directement la référence à l'objet.
    puis la séquence de code généré est la même que pour le cas précédent.
    mais c'est le compilateur qui le fait. cela est donc fait par le développeur avant que le produit ne soit livré. on peut donc se permettre de faire une analyse complexe et couteuse en temps. car ce qui en résultera sera un code efficace. de plus tout cela ne dépend que de la signature de la fonction

    dans l'interprète javascript en javascript un tel traitement dépendrait de l'appel. il faudrait donc le faire à chaque appel.
    on exécuterait donc un algo complexe qui ferait beaucoup d'opérations pour déterminer la meilleur stratégie. pour au final
    faire très peut d'opérations pour réellement passe l'argument. ce sur coup se ferait à chaque appel de fonction. ce qui est énorme. avec un tel algo on aurait quelque chose qui prendre plus 90% à choisir quoi faire et 10% à le faire.
    il est donc globalement plus efficace de toujours faire la même chose ce qui divise le temps par 10
    même si parfois l'ors d'un appel une autre façon aurait fait gagné 1%

    Si tu maitrise un minimum java tu peux facilement avec nashhorn ou rhino faire du pas à pas pour voir comment l'interprète travaille. tu verras que même si les implémentation son différentes que les techos sont différente les deux interprètes passent les arguments de la même façon.

    Si tu maitrise C/C++ fait pareil avec Geko JascriptCore ou V8 tu verra là encore que les technos diffèrents que les implémentation diffèrent mais qu'il passent tous les paramètres de la même façon que Nashorn et rhino.



    Citation Envoyé par galerien69
    on peut très bien imaginer que la référence est créée pour un primitif dès qu'on essaie de l'assigner à une variable.
    Une variable en javascript c'est trois trois mots dans une hashtable le premier point ver la string représentant son nom. le deuxième représente son type et le troisième contient une valeur simple
    soit la valeur pour les Number et Boolean, soit l'adresse de l'objet.
    en javascript les valeur des type primitif sont donc stocké dans la table des symbole.
    il ne viendrait à l'idée de personne lorsqu'il a besoin d'une variable int de créer un variable de type référence à un int
    puis créer le int et enfin affecter la référence à la variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //pour faire 
    int i =0;
    //on ne fait surtout pas 
    int &i;
    int j = 0;
    i =&j;
    non seulement ça rendrait le code complexe pour la suite vu qu'on a une référence et pas une variable. mais c'est inutile. javascript est restrictif sur les choix il ne te permet que de faire
    et rien d'autre.

    Citation Envoyé par galerien69
    idem elle n'est pas forcément crée si dans la fonction on ne s'en sert pas.
    Un cas peu probable, pas très productif, mais un cas quand même!
    si il s'agit la d'un problème d'optimisation globale. il suffit de voir le temps de compilation d'un programme C/C++
    ce temps dans un interprète s'il appliquait les mêmes méthode se ferait systématiquement à tout les appels. soit des centaine de millier de fois. mieux vaut systématiquement créer la chaine dans le tas et passer une référence à la fonction que de dépenser des milliers de cycle d'horloge d'introduire des ruptures du pipeline pour voir si on peut en gagner quelque centaines.

    c'est toujours vrai dans tout processus.
    si tu trouve un algo sytématique qui dans 10 ou 20 % des cas n'est pas optimal
    mieux vaut l'utiliser que d'utiliser un algo complexe qui dans tout les cas introduira 10% de temps de traitement en plus.

    A+JYT

  6. #26
    Membre averti
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Points : 362
    Points
    362
    Par défaut
    Citation Envoyé par sekaijin Voir le message
    non en javascript les type primitif ne sont jamais traité par référence il le sont par valeur

    et pour les type complexe il sont toujours traité par référence.
    peut importe la définition de la fonction en javascript ce n'est pas la signature de la fonction qui détermine le fonctionnement d'un appel.
    c'est le moteur javascript
    Merci sekaijin !

    Et histoire d'enfoncer le clou

    peut importe la définition de la fonction en javascript ce n'est pas la signature de la fonction qui détermine le fonctionnement d'un appel
    Donc,

    Je voudrais savoir s'il est possible de passer par reference un argument en javascript ?
    c'est non !

    Mais, est-ce que certains types de données sont passés par référence ?

    c'est oui. (bien que je maintienne qu"en terme de représentation on est plus proche d'un passage par ... bon, allez je lache l'affaire )

  7. #27
    Invité
    Invité(e)
    Par défaut
    http://www.ecma-international.org/ecma-262/5.1/#sec-8.7

    Une variable en javascript c'est trois trois mots dans une hashtable le premier point ver la string représentant son nom. le deuxième représente son type et le troisième contient une valeur simple
    soit la valeur pour les Number et Boolean, soit l'adresse de l'objet.
    Donc déjà non. Ca c'est implem dependant.
    Une variable c'est une référence, et une référence c'est bien trois trucs en table mais juste le nom, la valeur et un flag pour strict mode. valuer qui est primitive ou pas


    en javascript les valeur des type primitif sont donc stocké dans la table des symbole.
    Pareil il n'est nulle part fait mension de table des symboles c'est encore implem dependant.

    il ne viendrait à l'idée de personne lorsqu'il a besoin d'une variable int de créer un variable de type référence à un int
    puis créer le int et enfin affecter la référence à la variable.
    et pourtant c'est le cas.
    quand tu écris var i = 10
    tu crées une référence de nom 'i', dont la base vaut Number(10).

    For example, the left-hand operand of an assignment is expected to produce a reference
    Je peux me tromper, mais de manière générale, je préférence me fier à la spec qu'à un reverse de moteur js. (aussi pertinent soit-il)

    ps:
    //on ne fait surtout pas
    int &i;
    est invalide
    juste pour la mémoire, &i est invalide il manque un = qqch.
    De manière générale on parle pas de référence C++, mais de référence js.
    On peut implem une référence avec la hashtable, c'est probablement le cas (j'ai jamais eu la curiosité) mais savoir si on store le type et la valeur ou bien juste un objet primitif ou pas, c'est au choix..

    si tu trouve un algo sytématique qui dans 10 ou 20 % des cas n'est pas optimal
    mieux vaut l'utiliser que d'utiliser un algo complexe qui dans tout les cas introduira 10% de temps de traitement en plus.
    la spec est écrite pour tenir compte des perfs, mais les algos mis en place pour des raisons de perf ne constituent pas la spec!

    Typiquement, si tu crées une ref de string quand tu la passes à la fonction, ok pour les raisons de perf, mais si c'est pas speccé ya rien qui t'oblige à faire ainsi.

    Bon ici, c'est vrai que ya quand même arguments dans l'histoire, et pe que dans arguments sont storés des ref (je sais pas j'ai pas lu)

    bref quelquepart on s'en tape un peu de comment le moteur est implémenté si la question porte sur du js (sans aborder les perfs liées d'écriture du js)

  8. #28
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Citation Envoyé par galerien69
    Pareil il n'est nulle part fait mension de table des symboles c'est encore implem dependant.
    non la table des symbole est une obligation pour compiler ou interpréter un langage.
    dans un langage compilé, il est nécessaire de la conserver tout le temps de la compilation, ensuite seule les référence peuvent être utilisé et cela ne dépend que du compilateur et des specs du langage.
    pour un langage interprété pour que le moteur lorsqu'il rencontre un symbole dans le code source sache à quoi celui fait référence il est nécessaire de conserver une association entre le texte représentant le symbole et l'objet que référence le symbole. donc non c'est purement théorique c'est une nécessité de l'interprétation.

    libre au développeur de choisir son implémentation. la table doit exister c'est tout peu importe sa forme.

    Citation Envoyé par galerien69
    et pourtant c'est le cas.
    quand tu écris var i = 10
    tu crées une référence de nom 'i', dont la base vaut Number(10).
    La encore NON en javascript Number(10) et 10 sont deux chose différente Number(10) est un objet don un membre contient 10 qui possède d'autres membres c'est donc une structure complexe faite de plusieurs cellules mémoires
    et si on l'affecte à une variable il le sera par référence. alors que 10 est une seule cellule qui sera affecté par valeur.


    Citation Envoyé par galerien69
    Je peux me tromper, mais de manière générale, je préférence me fier à la spec qu'à un reverse de moteur js. (aussi pertinent soit-il)
    donc respectons la spec tout affectation de type primitif se fait par valeur
    toute affectation de type complexe se fait par référence.

    Jamais en javascript on ne va crée dans le tas de nombre ou de booléen pour affecter l'adresse de cet int ou de ce booléen à une variable.

    Jamais en javascript on ne passera un objet complexe à une fonction par valeur.
    Tu peux vouloir imaginer ce que tu veux javascript est défini ainsi.
    A+JYT

  9. #29
    Membre confirmé

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Points : 545
    Points
    545
    Par défaut
    Citation Envoyé par sekaijin
    Number(10) est un objet don un membre contient 10 qui possède d'autres membres c'est donc une structure complexe faite de plusieurs cellules mémoires
    et si on l'affecte à une variable il le sera par référence. alors que 10 est une seule cellule qui sera affecté par valeur.
    et pourtant sur le moteur V8 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    C:\Work>node
    > function inc(x) { x++; x.lastInc = new Date();}
    undefined
    > var a = new Number(10);
    undefined
    > a
    {}
    > inc(a)
    undefined
    > +a
    10
    > a
    {}


    Je pense que l'auteur de ce thread c'est déjà pendu
    ShaderElement : Bénéficier de l’accélération graphique simplement par une nouvelle balise HTML <shader>
    ODE.js : portage JavaScript du célèbre moteur physique 3D Open Dynamics Engine

  10. #30
    Invité
    Invité(e)
    Par défaut
    ne me fais pas dire ce que j'ai pas dit:
    Je n'ai pas dit que la table n'existe pas. J'ai dit qu'on l'implémente comme on veut.
    libre au développeur de choisir son implémentation.
    on est d'accord sur ce point (ce que je contestais dans mon précédent message, c'est que tu déclares comme vérité établie que la hashtable doit contenir précisément type et valeur alors qu'on représente ca comme on veut)

    La encore NON en javascript Number(10) et 10 sont deux chose différente Number(10) est un objet
    non, 10 est de type Number.
    Number(10) est également de type Number (qui est un type primitif et qui vaut 10)
    A ne pas confondre avec new Number qui effectivement est un object

    c'est donc une structure complexe faite de plusieurs cellules mémoires
    Pourquoi parler de celulles mémoires!!!

    donc respectons la spec tout affectation de type primitif se fait par valeur
    où as-tu lu ca?

  11. #31
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    11.2.3 Function Calls
    1. Let ref be the result of evaluating MemberExpression.
    2. Let func be GetValue(ref).
    3. Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4).
    4. ...


    11.2.4 Argument Lists
    1. Let ref be the result of evaluating AssignmentExpression.
    2. Let arg be GetValue(ref). (see 8.7.1)
    3. Return a List whose sole item is arg.


    8.7.1 GetValue (V)
    1. If Type(V) is not Reference, return V.
    2. ...


    donc si type n'est pas une référence on passe la valeur
    A+
    PS: il est nécessaire de conserver le type dans la table des symboles car l'interprète en a besoin pour le transtypage lors de l'utilisation de certains opérateur comme + et le type peux changer au fil du temps. on garde donc toujours un contenu ref ou value et le type de ce contenu.

    A+JYT

  12. #32
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    @pegase: l'opérateur ++ fait un cast en primitive Number, c'est pour ça qu'on perd la référence. Il faudrait trouver le moyen d'aller modifier la propriété interne [[PrimitiveValue]] pour garder la référence, mais ça je sais pas comment on fait. Et puis ça n'a pas beaucoup d'intérêt en fait
    One Web to rule them all

  13. #33
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Je suis impressionné par la tournure que prend cette conversation

    Je crois que le mieux pour avoir la réponse à la question est de tester différents langages pour se convaincre soi-même.

    Sachant que le terme « référence » (avec une bonne grosse paire de guillemets) représente différents concepts et que, apparemment, on n'est pas tous d'accord sur lequel.

    Pour moi il y a seulement deux concepts :

    – Concept « référence Java » : la VM ou l'interpréteur choisit la façon de passer l'argument en fonction de son type. Un type primitif est passé par valeur (a.k.a. par copie) ; un type complexe est passé par référence. Le développeur n'a pas de contrôle sur ce mécanisme. C'est ce qui se passe en JavaScript.

    – Concept « référence C++ » : on active ce mécanisme en utilisant le symbole & associé à un type, par exemple int&. C'est ce qui se passe en PHP. L'avantage de cette version du concept est qu'on peut passer des types primitifs par référence, un entier dans mon exemple.

    Reste à avoir duquel de ces deux concepts (ou d'un autre que je ne connais pas ) Kouamé Josué voulait parler.

    Citation Envoyé par p3ga5e
    Je pense que l'auteur de ce thread c'est déjà pendu
    Honnêtement, je commence à m'inquiéter…
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  14. #34
    Membre averti
    Profil pro
    à la bougie alors
    Inscrit en
    Mai 2006
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : à la bougie alors

    Informations forums :
    Inscription : Mai 2006
    Messages : 224
    Points : 362
    Points
    362
    Par défaut
    Belle tentative ! mais le concept est le même dans les deux cas. La différence n'est pas conceptuelle, mais de savoir qui choisit le type du passage de l'argument. Ce que tu explique d'ailleurs trés bien

    Et puis immutable passage par valeur tout ça, rien n'empêche de tricher

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function inc(x) {
        if ( x instanceof Number ) {
            var y = 1+x;
            x.valueOf  = function(){return y};
            x.toString = function(){return ""+y};
        }
    }

  15. #35
    Membre confirmé

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Points : 545
    Points
    545
    Par défaut
    Citation Envoyé par SylvainPV Voir le message
    @pegase: l'opérateur ++ fait un cast en primitive Number, c'est pour ça qu'on perd la référence
    Oula je n’étais pas au courant de cela …
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    > var a = new Number(10)
    undefined
    > a instanceof Object 
    true
    > a++
    10
    > a instanceof Object 
    false
    C’est un vrai nid à bogues !

    Du coup à quoi ça sert d’instancier des primitives ?
    ShaderElement : Bénéficier de l’accélération graphique simplement par une nouvelle balise HTML <shader>
    ODE.js : portage JavaScript du célèbre moteur physique 3D Open Dynamics Engine

  16. #36
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    instancier des primitives ? tu veux dire par leurs équivalents objet ? Ben à rien 99% du temps, mais je m'en suis servi récemment (voir 3 topics en dessous: http://www.developpez.net/forums/d14...on-type-volee/)

    Généralement on déconseille d'utiliser ces wrappers de primitives, parce que comme tu dis c'est un vrai nid à bugs (et encore, mon préféré c'est if(new Boolean(false)){ alert('wtf'); }). D'ailleurs ça n'a pas loupé, on m'a fait la remarque dans le topic ^^

    Pour l'incrémentation, si tu veux que l'opération soit faite avant le renvoi de la valeur de retour, il faut mettre le "++" devant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var a = new Number(10);
    ++a; //11
    oui je sais, pourquoi faire simple quand on peut faire compliqué
    One Web to rule them all

  17. #37
    Invité
    Invité(e)
    Par défaut
    donc si type n'est pas une référence on passe la valeur
    à savoir:
    someFunc('test')
    il y aura-t-il création d'une ref pointant vers 'test' où bien une copie pure et dure de 'test'.
    Tout laisse supposer le premier cas, mais pour y répondre, il faut bouffer du v8 (ou ses camarades)
    il y a création d'une référence.



    si on l'affecte [l'objet] à une variable il le sera par référence.
    alors que 10 est une seule cellule qui sera affecté par valeur.
    (entre crochets c'est de moi, tu réfèrais à Number(10) mais Number(10) n'est pas un object)

    il est également intéressant pour une affectation de regarder ce qu'il se passe lorsque l'on utilise un simple assignment

    idem l'appel
    on crée une ref de base primitive de valeur 10
    mais également
    que contient la base de j. une ref vers la base de i ou la valeur 10 ?

    je n'ai pas la réponse (mais j'espère un quote de la spec évidemment).

  18. #38
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    j contient la valeur 10, puisque c'est une primitive. Où est-ce que vous voulez en venir à la fin ? J'ai l'impression que vous avez fait trois fois le tour du sujet en employant des mots différents. Maintenant le nouveau mot c'est "base"
    One Web to rule them all

  19. #39
    Invité
    Invité(e)
    Par défaut
    je veux en venir nulle part. Plutot que gober des trucs pré établis et observés (n'importe qui peut voir que tout se fait par valeur, les références semblant copiées..par valeur), c'est plus intéressant de voir si c'est le cas tout le temps et si oui qu'est-ce qui l'approuve.
    de même pour un type primitif tu affirmes que j contient 10. Mais pourquoi. (pourquoi dans le sens qu'est-ce qui justifie une telle déclaration)

    Pourquoi j ne contiendrait pas une ref à i. Et en utilisant j, la base de i étant un primitif, la base de j serait duppliquée?
    Maintenant le nouveau mot c'est "base"
    le nouveau mot il est pas nouveau depuis le dernier poste.

    et quel est le problème d'utiliser des nouveaux mots à partir du moment où ils sont définis?

  20. #40
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    la réponse est dans la spec
    celle-ci décrit bien comment on passe un argument
    de même elle décrit comment se fait une affectation a une variable dans tous les cas
    cela se passe au travers de 8.7.1 GetValue qui renvoie la valeur si le type n'est pas une référence.
    Citation Envoyé par sekaijin Voir le message
    11.2.3 Function Calls
    1. Let ref be the result of evaluating MemberExpression.
    2. Let func be GetValue(ref).
    3. Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4).
    4. ...


    11.2.4 Argument Lists
    1. Let ref be the result of evaluating AssignmentExpression.
    2. Let arg be GetValue(ref). (see 8.7.1)
    3. Return a List whose sole item is arg.


    8.7.1 GetValue (V)
    1. If Type(V) is not Reference, return V.
    2. ...


    donc si type n'est pas une référence on passe la valeur
    Donc lorsque quelqu'un pose la question la réponse est
    "Javascript utilise toujours des références pour tout ce qui n'est pas type primitif et des valeur dans le cas contraire"

    vu que certains dans la discu ne comprenaient pas j'ai tenter d'expliquer comment fonctionne le moteur.
    Mais c'est une définition du langage ce n'est pas un pb d'implémentation, ni de choix du développeur javascript.
    C'est simplement dans la spec.

    on peut le déplorer. on peut l'approuver. on peut imaginer ce que l'on veut. c'est la spec.
    il n'y a rien a gober qui sortirait d'un chapeau. c'est la spec.

    ce qui m'a fait réagir c'est que l'expérience décrite pour montrer que ce n'est pas un passage par référence était fausse.
    Changer la référence d'une variable locale dans une fonction ne pourra jamais quelque soit le langage changer la référence d'une variable passé en paramètre.
    la conclusion était donc fausse.

    et il y a des vérités incontournable dans la théorie des langages.
    lorsqu'on passe une valeur à une fonction on peut l'utiliser mais pas la modifier
    lorsqu'on passe une référence à une valeur à une fonction on peut modifier la valeur mais pas la référence.

    de plus dans cette discussion j'ai constaté beaucoup de confusions dans la définition de variable
    toujours d'un point de vu purement théorique (donc indépendamment du l'implémentation) une variable c'est
    un symbole, dans un contexte, associé à un type et une valeur.
    même les langages les plus faiblement typé en passent par là.

    et pour finir tout système d'analyse et de traitement lexical et sémantique a besoin de conserver l'ensemble des symboles.
    c'est pour cette raison que cet ensemble est présent dans les compilateurs et aussi dans les interprètes. mais aussi dans les système de traduction ou d'analyse du langage naturel. c'est un problème purement algébrique un ensemble de terminaux + une grammaire produit des terminaux. c'est une condition nécessaire à la constitution d'un langage. (je sais je simplifie mais je ne vais pas mettre toute la théorie ici, il existe des bouquins pour ça)

    A+JYT

Discussions similaires

  1. Réponses: 4
    Dernier message: 29/04/2010, 07h30
  2. Passage de 'pipe' à une fonction ?
    Par laurent_ifips dans le forum POSIX
    Réponses: 2
    Dernier message: 25/11/2005, 08h06
  3. [JAVASCRIPT] passage d'argument à une fonction
    Par LE NEINDRE dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 03/06/2005, 19h17
  4. [TASM] Passage d'argument à une macro
    Par sorry60 dans le forum Assembleur
    Réponses: 13
    Dernier message: 23/04/2005, 19h22
  5. Passer une fonction comme argument à une fonction
    Par Cocotier974 dans le forum Général Python
    Réponses: 4
    Dernier message: 29/06/2004, 14h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo