33

Pomagałem koledze debugowania kodu dzisiaj i zauważyłem dziwne zachowanie z console.log() w Google Chrome: WydajeGoogle Chrome console.log() niezgodność z obiektami i tablicami

że jeśli:

  1. Tworzenie zagnieżdżonej tablicy (np [[345 „test”]])

  2. Log tablicę do konsoli z console.log().

  3. zmodyfikować jeden z wewnętrznych tablic wartości, a następnie console.log() wyjściowy będzie później wartość - nie wartości tablicy w czasie console.log() została wykonana.

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"] 

JSFiddle Example

Takie zachowanie nie zdarza się w Firefoksie.

Należy również pamiętać, że jeśli przejdę przez jego linię kodu po linii w debugerze Chrome, to console.log() wyświetli prawidłowe wartości.

Czy istnieje wyjaśnienie tego dziwnego zjawiska, czy jest to tylko błąd w Google Chrome?

EDIT:

mam zawężony kroki, aby odtworzyć niespójne console.log() zachowanie:

Jeśli dodasz ten skrypt na swojej stronie:

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

i otwórz go w nowe okno z oknem konsoli Chrome już otwarte, wówczas dane wyjściowe console.log() będą inne niż w przypadku ładowania strony z oknem konsoli zamknięte. Here's a JSFiddle that demonstrates that.

W pierwszym przypadku, przy otwartym oknie konsoli, console.log() wyświetli bieżącą wartość tablicy (tzn. Dwie pozycje).

W drugim przypadku, w oknie konsoli początkowo zamknięte i otwarte tylko po wczytywania strony console.log() wyjście będzie późniejsze wartości tablicy (to znaczy trzy pozycje).

Czy jest to błąd w funkcji przeglądarki Google Chrome o numerze console.log()?

+0

Choć nie wiem jak, dokładnie, to nie jest błąd, Chrome robi tego typu rzeczy z pewną częstotliwością; możesz również rejestrować wynik żądania AJAX; wypełnia go z mocą wsteczną, prawdopodobnie dla jasności podczas logowania. Jestem zbyt nieudolny, aby zacząć wyjaśniać, dlaczego właśnie miałem podobny problem.Każdy kod zależny od poprawnej wartości działałby dobrze. – Jonline

+1

Wygląda na to, że wartość zarejestrowana na konsoli jest wartością * bieżącą *. Dowolna wartość skalarna w obiektach odniesienia nie zostanie obliczona, dopóki nie rozszerzysz obiektów w konsoli Wyjście – Phil

+0

Wydaje się dziwne, że wyniki 'console.log()' będą podlegały warunkom wyścigu. Kiedy przechodziłem przez mój kod współpracowników, 'console.log()' wyprowadzałby wartości, których się spodziewaliśmy, ale przy normalnym wykonywaniu wyprowadzałby później zmodyfikowaną wartość - wydaje się, że chcesz mieć wartości tablicy w dokładny moment 'console.log()' jest wykonywany. –

Odpowiedz

26

Po wielu kopaniu stwierdziłem, że został zgłoszony jako błąd, poprawiony w Webkit, ale najwyraźniej nie został jeszcze wciągnięty do Google Chrome.

O ile mogę powiedzieć, problem został zgłoszony tutaj: https://bugs.webkit.org/show_bug.cgi?id=35801:

Opis Od mitch Kramer 2010-03-05 11:37:45 CET

1) utworzyć obiekt dosłowne z jednego lub większej liczby właściwości

2) console.log tego obiektu, ale pozostawić to zamknięte (nie rozwinąć go w konsoli)

3) zmiany jednej z właściwości do nowej wartości

Teraz otwórz konsolę console.log, a zobaczysz, że z jakiegoś powodu ma nową wartość, mimo że jej wartość była inna w momencie jej wygenerowania.

Należy zauważyć, że jeśli go otworzysz, zachowa poprawną wartość, jeśli nie było to jasne.

odpowiedź od dewelopera chrom:

Komentarz # 2 od Pavel Feldman 2010-03-09 06:33:36 CET

Nie sądzę, że kiedykolwiek będzie naprawić ten. Nie możemy sklonować obiektu po wrzuceniu go do konsoli, a także nie możemy słuchać zmian właściwości obiektu, aby był zawsze aktualny.

Powinniśmy jednak upewnić się, że dotychczasowe zachowanie jest oczekiwane.

fix był realizowane dwa i pół roku później, w dniu 9 sierpnia 2012 roku na Webkit (http://trac.webkit.org/changeset/125174), ale nie wydaje się, aby uczyniły to w Chrome jeszcze.

dzień dzisiejszy, wysypywania obiektu (array) do konsoli spowoduje właściwości obiektu jest odczytu od obiektu rozszerzalności konsoli (tj leniwie). Oznacza to, że zrzucanie tego samego obiektu podczas mutowania będzie trudne przy debugowaniu za pomocą konsoli.

Ta zmiana rozpoczyna generowanie skróconych podglądów obiektów/tablic w momencie ich rejestrowania i przekazuje te informacje do interfejsu użytkownika. Dzieje się tak tylko wtedy, gdy front-end jest już otwarty, działa tylko w konsoli console (.log), a nie w konsoli.

+0

"Oznacza to, że zrzucenie tego samego obiektu podczas mutowania go będzie trudne do debugowania za pomocą konsoli ", właśnie zdałem sobie z tego sprawę kilka miesięcy temu i doprowadziło mnie to do szału. – Fahmi

+0

Dziękuję. Od kilku dni wyciągam włosy i próbuję zrozumieć, co jest nie tak z moim kodem. Tutaj cały problem dotyczył Chrome. – kojow7

+2

Jego 2017 rok i nadal dzieje się z zagnieżdżonymi wartościami obiektów. Wczoraj spędziłem wiele godzin na debugowaniu wtyczki kodującej, ponieważ nie pokazywałem wartości, okazało się, że było to chromowane, gdy logowałem zadanie obj i zagnieżdżałem obiekt przed/po. – OneEyed

3

Znalazłem obejście tego błędu/funkcji.

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

Edycja: Niestety nie będzie to działać w przypadku niepoprawnych wartości, takich jak funkcje. Użyj tutaj innego narzędzia do klonowania. Przykładem

jQuery:

console.log($.extend({}, myObject)); 
+0

Dobry pomysł! Można również zastąpić funkcję 'toString'. –

+0

Niestety, nie wszystkie obiekty mogą być uszeregowane. np. 'JSON.stringify (document.body)' – ahui