2010-12-14 44 views
1

En Javascript The Good Parts, il est écrit:Pourquoi cet exemple Javascript copie-t-il la valeur de la variable au lieu de passer par référence?

alt text

donc j'attendre avec l'exemple de code suivant à la sortie puisque "les objets ne sont jamais copiés mais passés autour par référence", alors pourquoi sort-il ?

var page_item = { 
    id_code : 'welcome', 
    title : 'Welcome', 
    access_groups : { 
     developer : '0010', 
     administrator : '0100' 
    } 
}; 
page_item.access_groups.member = '0000'; 
var member = page_item.access_groups.member; 
member = '1001'; 

$('p#test').html(page_item.access_groups.member); //should be "1001" but is "0000" 

Ajouté:

@Gareth @ David, merci, voilà ce que je voulais montrer dans cet exemple, fonctionne:

var page_item = { 
    id_code : 'welcome', 
    title : 'Welcome', 
    access_groups : { 
     developer : '0010', 
     administrator : '0100' 
    } 
}; 
var page_item2 = page_item; 
page_item2.access_groups.developer = '1001'; 

$('p#test').html(page_item.access_groups.developer); //is '1001' 
+0

Ceci est le même en Python, et facilement expliqué là ('x.y = ...' est un appel de méthode sur 'x' '__dict__',' x = ... 'n'est pas un appel de méthode). @Potential répondeurs: Y a-t-il un raisonnement similaire dans JS? – delnan

+0

@delnan - 'x.y =' n'est pas un appel de méthode en Javascript. (Eh bien, il est * possible dans ECMAScript de définir des méthodes setter et getter pour les propriétés des objets mais ce n'est pas le paradigme qui a causé la confusion dans cette question) – Gareth

Répondre

4

Ne pensez pas à la référence par renvoi dans le contexte C++, car ce n'est pas la même chose.

var member = page_item.access_groups.member // Sets member to this value 
member = '1001'; // Now sets it to another value 

S'il y avait une méthode sur les chaînes qui les ont changé, alors ceci:

member.removeLastLetter(); 

modifieraient page_item.access_groups.member. Cependant, avec votre = vous changez de référence de la variable, et non l'objet qu'il a précédemment référencé

+0

Je réfléchissais à la question de savoir si c'est réellement correct ou non, et une chose importante à noter est que String est aussi un objet. Après avoir réalisé cela, ça a plus de sens pour moi. – Sam

1

Parce que page_item.access_groups.member est une chaîne et non un objet .

+0

Même si 'page_item.access_groups.member = {}', une ligne suivante ' var member = page_item.access_groups.member; member = {foo: 1001} 'ne mettrait pas à jour l'objet' page_item.access_groups.member' – Gareth

0

Ceci est probablement se défoncé par JS-Gurus mais, fondamentalement, il va comme ceci:

objets sont passés par référence.
Les chaînes (nombres, etc ... essentiellement des variables 1 dimensionnelles) sont passées par valeur. J'ai essayé de comprendre les longues explications sur les types de données, mais j'ai sérieusement besoin d'un peu de travail et je n'ai pas eu le temps d'y regarder de plus près.

+0

PBR et PBV sont fondamentalement des mythes en javascript. Le point principal est, si vous avez une référence à ** n'importe quoi ** (chaîne ou autre) dans une variable 'var x', dès que vous écrivez' x = ... 'vous êtes * rejetant * votre référence initiale et en créer un nouveau, par opposition à l'exécution d'une opération sur la valeur que vous avez précédemment référencée. – Gareth