web-dev-qa-db-fra.com

Google Chrome console.log () incohérence avec les objets et les tableaux

J'aidais un collègue à déboguer du code aujourd'hui et j'ai remarqué un comportement étrange avec console.log() dans Google Chrome:

Il semble que si vous:

  1. Créez un tableau imbriqué (par exemple, [[345, "test"]])

  2. Connectez la baie à la console avec console.log().

  3. Modifiez l'une des valeurs internes du tableau, puis console.log() affichera la dernière valeur - pas les valeurs du tableau au moment la console.log() a été exécutée.

JavaScript :

var test = [[2345235345,"test"]]
console.log(test);
test[0][0] = 1111111;
// outputs: [[1111111,"test"]]

var testb = {};
testb.test = "test";
console.log(testb);
testb.test = "sdfgsdfg";
// outputs: {"testb":"test"}


var testc = ["test","test2"];
console.log(testc);
testc[0] = "sdxfsdf";
// outputs: ["test","test2"]

Exemple JSFiddle

Ce comportement ne se produit pas dans Firefox.

À noter également, si je parcourais son code ligne par ligne dans le débogueur Chrome, alors console.log() produirait les valeurs correctes.

Y a-t-il une explication à cet étrange phénomène ou s'agit-il simplement d'un bug avec Google Chrome?

MODIFIER:

J'ai réduit les étapes pour reproduire le comportement incohérent de console.log():

Si vous ajoutez ce script à votre page:

var greetings=['hi','bye'];
console.log(greetings);
setTimeout(function(){
    greetings.Push('goodbye');
},3000);

et ouvrez-le dans une nouvelle fenêtre avec la fenêtre de console Chrome déjà ouverte , puis la fonction console.log() la sortie sera différente de si vous chargez la page avec la fenêtre de console fermée . Voici un JSFiddle qui le démontre .

Dans le premier cas, avec la fenêtre de console déjà ouverte, console.log() affichera la valeur actuelle du tableau (c'est-à-dire deux éléments).

Dans le deuxième cas, avec la fenêtre de la console initialement fermée et ouverte uniquement après la page se charge, console.log() affichera les dernières valeurs du tableau (c'est-à-dire trois éléments).

Est-ce un bogue dans la fonctionnalité console.log() de Google Chrome?

47
Elliot B.

Après beaucoup de recherches, j'ai constaté que cela avait été signalé comme un bug, corrigé dans Webkit, mais apparemment pas encore intégré à Google Chrome.

Pour autant que je sache, le problème a été initialement signalé ici: https://bugs.webkit.org/show_bug.cgi?id=35801 :

Description De mitch kramer 2010-03-05 11:37:45 PST

1) créer un littéral objet avec une ou plusieurs propriétés

2) console.log cet objet mais laissez-le fermé (ne le développez pas dans la console)

3) changez l'une des propriétés en une nouvelle valeur

ouvrez maintenant ce console.log et vous verrez qu'il a la nouvelle valeur pour une raison quelconque, même si sa valeur était différente au moment où il a été généré.

Je dois souligner que si vous l'ouvrez, il conservera la valeur correcte si ce n'est pas clair.

Réponse d'un développeur Chromium:

Commentaire # 2 De Pavel Feldman 2010-03-09 06:33:36 PST

Je ne pense pas que nous allons jamais réparer celui-ci. Nous ne pouvons pas cloner un objet après l'avoir déposé dans la console et nous ne pouvons pas non plus écouter les modifications des propriétés de l'objet afin de le rendre toujours réel.

Nous devons cependant nous assurer que le comportement existant est attendu.

Un correctif a été implanté deux ans et demi plus tard le 9 août 2012 pour Webkit ( http://trac.webkit.org/ changeset/125174 ), mais il ne semble pas encore en avoir fait Chrome pour l'instant.

À partir d'aujourd'hui, le dumping d'un objet (tableau) dans la console entraînera la lecture des propriétés des objets lors de l'expansion des objets de la console (c'est-à-dire paresseusement). Cela signifie que le vidage du même objet tout en le mutant sera difficile à déboguer à l'aide de la console.

Cette modification commence à générer des aperçus abrégés pour les objets/tableaux au moment de leur journalisation et transmet ces informations au frontal. Cela ne se produit que lorsque le front-end est déjà ouvert, cela ne fonctionne que pour console.log (), pas pour l'interaction de console en direct.

37
Elliot B.

J'ai trouvé une solution de contournement pour ce bogue/fonctionnalité.

console.log(JSON.parse(JSON.stringify(myObject)));

Edit: Malheureusement, cela ne fonctionnera pas pour les valeurs non primitives comme les fonctions. Utilisez un autre utilitaire de clonage ici.

exemple jQuery:

console.log($.extend({}, myObject));
9
cheeZer