2
votes

Pourquoi la valeur du tableau n'est-elle modifiée qu'après la première fonction?

J'ai une fonction qui inverse un tableau:

arr = output;

et une fonction qui crée un tableau de portée locale et envoie les valeurs dans l'ordre inverse:

reverseArr(arrayValue); //[5, 4, 3, 2, 1]
console.log(arrayValue); //[1, 2, 3, 4, 5]

Supposons qu'il y ait un élément:

reverseArray(arrayValue); // [5, 4, 3, 2, 1]
console.log(arrayValue); // [5, 4, 3, 2, 1]

Si j'appelle la première fonction avec arrayValue comme argument, arrayValue est changé:

let arrayValue = [1, 2, 3, 4, 5];

Cependant, si j'appelle la deuxième fonction avec arrayValue:

function reverseArr(arr) {
  let output = [];
  for(let i of arr) {
    output.unshift(i);
  }
  arr = output;
  return arr;
}

arrayValue n'est pas modifié même si j'ai attribué la valeur inversée à l'argument avant le retour:

function reverseArray(array) {
  for(let i = 0; i <= Math.floor(array.length / 2); i++) {
    let old = array[array.length - 1 - i];
    array[array.length - 1 - i] = array[i];
    array[i] = old;
  }
  return array;
}

quelqu'un peut-il m'expliquer pourquoi?

Merci d'avance.


9 commentaires

Je ne pense pas que le unshift fait ce que vous pensez qu'il fait. Lisez developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .


Voir aussi ici , qui décrit une meilleure approche utilisant push .


Est-ce que cela répond à votre question? La fonction Javascript ne modifie pas le tableau (référence?)


@RobertHarvey euh .... unshift () est la bonne chose à utiliser ici .... OP inverse un tableau donc il ajoute à l'avant, votre suggestion est de l'ajouter à la fin ..... Donc OP serait récupère le même ordre de tableau puisque la boucle ne recule pas ...


@epascarello: Dans l'exemple que je LIÉ, la boucle est en train de reculer.


JS est pass-by-value , lorsque vous faites arr = output vous ne réaffectez que la variable locale arr . Vous ne remplacez pas le tableau arrayValue il faisait référence ni n'affectez l'autre variable ( arrayValue ) qui fait toujours référence à ce tableau. Dans votre premier exemple, vous modifiez directement ce tableau.


@RobertHarvey Oui et OP ne boucle pas à l'envers et votre premier commentaire est faux.


@epascarello. Lisez l'exemple que j'ai lié; c'est un code parfaitement bon. Au lieu de vous disputer avec moi, essayez d'utiliser votre temps de manière productive et postez une réponse appropriée.


Mon argument a commencé parce que votre tout premier commentaire est incorrect. Et si OP suivait le code dans le lien, il aurait toujours le même problème car il ne modifie pas le tableau d'origine.


3 Réponses :


4
votes

En gros, vous prenez un nouveau tableau avec

arr.length = 0;
arr.push(...output);

et plus tard, vous affectez le nouveau tableau au paramètre arr

arr = output;

Vous avez maintenant deux références d'objet, une arr de la portée externe et une nouvelle de output .

Pour surmonter cela, vous devez conserver la référence d'objet de array . Pour obtenir un nouveau contenu dans un tableau existant, vous pouvez vider le tableau et pousser les valeurs du nouveau tableau.

let output = [];


0 commentaires

2
votes

Lorsque vous faites arr = output en reverseArr vous faites référence à un nouveau tableau. En d'autres termes, arrayValue dans le contexte externe et arr font référence à deux objets différents.

Vous ne pouvez pas modifier la valeur de la variable avec laquelle la fonction est appelée. Si vous avez une référence à l'objet, vous pouvez le muter, mais vous ne pouvez pas faire en sorte que la variable extérieure fasse référence à un autre objet.


0 commentaires

1
votes

Fondamentalement, votre première fonction inverse la liste en place (c'est -à- dire qu'elle opère directement sur la liste elle-même, sans construire une nouvelle liste), tandis que la deuxième fonction inverse la liste hors de place , en construisant une nouvelle liste dont le contenu est l'inverse de la liste originale.

Lorsque vous travaillez sur place, les modifications que vous apportez au array à l'intérieur de la fonction sont directement appliquées à arrayValue .

La raison pour laquelle arr = output ne fonctionne pas comme vous l'entendez est à peu près ce à quoi les autres réponses font référence. À savoir, arr et arrayValue sont deux références différentes ("pointeurs"). Initialement, arrayValue et arr "pointent vers" le même tableau lorsque la fonction est appelée. Cependant, arr = output fait pointer arr vers la output liste nouvellement construite.


0 commentaires