2010-12-01 4 views
4

J'écrivais un programme javascript et l'exécutais dans Chrome 7, quand j'ai rencontré un comportement étrange. Maintenant, dans mon code, avec tout ce qui se passe, il m'a fallu du temps pour comprendre que ce n'était pas moi.Variable modifiée avant le fait, pouvez-vous expliquer ce comportement de Chrome V8?

J'ai distillé l'essence du code ci-dessous.

<html> 

<script> 

var data = [1,2,3,4,5]; 

var data_copy = []; 

for (var i=0; i<data.length; i++){ 
    data_copy.push(data[i]); 
} 

console.log("Printing before:"); 
console.log(data_copy); 

//alert(data_copy); 

console.log("------------------------"); 

for (var i=0; i<data_copy.length; i++){ 
    data_copy[i] = data_copy[i] * 1000; 
} 

console.log("Printing after:"); 
console.log(data_copy); 

</script> 

</html> 

Quand je lance ceci sur Chrome 7, je reçois la sortie qui suit dans la console Javascript:

Printing before: 
[1000, 2000, 3000, 4000, 5000] 
------------------------ 
Printing after: 
[1000, 2000, 3000, 4000, 5000] 

Comment se fait le premier appel à CONSOLE.LOG imprime la version modifiée de data_copy?

Maintenant, si je décommenter la « alerte » et exécuter le même code, je reçois ce que vous attendez normalement:

Printing before: 
[1, 2, 3, 4, 5] 
------------------------ 
Printing after: 
[1000, 2000, 3000, 4000, 5000] 

J'ai aussi essayé le code dans Node.js et je reçois le deuxième (normal) sortie.

Des idées?

Est-ce que cette optimisation JIT a mal tourné?

Ou est-ce que quelque chose me manque?

+0

Une conjecture est que le navigateur exécute l'appel de se connecter de manière asynchrone, après le changement. Mais pourquoi ferait-il cela? – Hejazzman

Répondre

4

Remplacez console.log(data_copy) par console.log(String(data_copy)).

console.log envoie effectivement l'objet par référence à la console de Chrome. alert interrompt votre script afin que le premier data_copy enregistré soit rendu avant la modification ultérieure; Sinon, le script entier s'exécute avant que la console ne renvoie la référence .

+0

Je peux voir l'appel console.log étant par référence, mais pourquoi il n'est pas rendu immédiatement? – Hejazzman

+0

Et pourquoi node.js, étant essentiellement V8, ne donne-t-il pas la même (mauvaise) sortie? – Hejazzman

+0

@foljs: La console ne fait pas partie du V8, elle fait partie de Chrome. Et le thread JS dans les navigateurs est forcément monothread, donc les gars de Chrome ont apparemment décidé de mettre en file d'attente l'objet et d'attendre la prochaine fois que le thread JS est libre, plus facile que de trouver le thread JS pour rendre un objet JS de l'intérieur du contexte arbitraire. – ephemient

1

Voir crbug.com/44720

Questions connexes