Jak mogę sprawić, by console.log pokazywała aktualny stan obiektu?

146

W Safari bez dodatków (a właściwie w większości innych przeglądarek), console.logpokaże obiekt w ostatnim stanie wykonania, a nie w stanie, w którym console.logzostał wywołany.

Muszę sklonować obiekt tylko po to, aby go wyprowadzić, console.logaby uzyskać stan obiektu w tym wierszu.

Przykład:

var test = {a: true}
console.log(test); // {a: false}
test.a = false; 
console.log(test); // {a: false}
Wesley
źródło
2
jsfiddle przykład problemu i różnych rozwiązań podanych poniżej: jsfiddle.net/luken/M6295
Luke
7
Jest to bardzo sprzeczne z intuicją, gdy funkcja dziennika wyprowadza na żywo odniesienie do obiektu. Nazywa się to zegarkiem , który różni się znacznie od wpisu dziennika. Nie ma większego sensu robienie tego podczas rejestrowania obiektu niż w przypadku rejestrowania zmiennej przechowującej pierwotną wartość.
faintsignal
2
Jak mogłem nigdy wcześniej tego nie przekroczyć? Uważam to za przerażające
ErikAGriffin

Odpowiedzi:

171

Myślę, że szukasz console.dir().

console.log()nie robi tego, co chcesz, ponieważ drukuje odniesienie do obiektu, a gdy go otwierasz, jest zmieniane. console.dirdrukuje katalog właściwości obiektu w momencie jego wywołania.

Poniższy pomysł na JSON jest dobry; możesz nawet przeanalizować ciąg JSON i uzyskać obiekt, który można przeglądać, taki jak dir ():

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

evan
źródło
38
Dla mnie w Chrome13 nie ma różnicy między console.logaconsole.dir
Andrew D.
Hm, to zaskakujące - działa w Firebug. Myślałem, że tak samo jest w Webkicie.
evan
1
To, co widzę w Chrome, to to, że jeśli otworzysz konsolę po uruchomieniu instrukcji log, to po jej rozwinięciu wykona leniwą ocenę. Ale jeśli konsola jest już otwarta (np. Otwierasz konsolę, a następnie klikasz przycisk odświeżania na stronie), przeprowadzi ona gorliwą ocenę - tj. Wydrukuje wartość w momencie uruchomienia instrukcji log.
Polemarch
6
Ponadto dir jest do JSON tak, jak płytkie kopiowanie do głębokiego kopiowania. console.dir () oceni tylko właściwości obiektu najwyższego poziomu (inne głębiej zagnieżdżone obiekty nie zostaną ocenione), podczas gdy JSON będzie działał rekurencyjnie.
Polemarch
9
Podobnie u mnie console.dirnie działa w Chrome (v33). Oto porównanie rozwiązań, które zaoferowali ludzie: jsfiddle.net/luken/M6295
Luke
71

To, co zwykle robię, jeśli chcę zobaczyć jego stan w momencie, gdy został zarejestrowany, to po prostu przekonwertować go na ciąg JSON.

console.log(JSON.stringify(a));
Alex Turpin
źródło
4
Świetnie, to była dla mnie miła wskazówka: po prostu musiałem to ponownie przeanalizować, aby obiekt był bezpośrednio w konsoli. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris
1
dzięki, to działa dla mnie! console.dir nie wydrukowała tego
ah-shiang han
1
co się stanie, jeśli zdarzy się, że Twój obiekt będzie zawierał okrągłą strukturę?
Alex McMillan
1
@AlexMcMillan Możesz użyć jednej z kilku bibliotek, które pozwalają na stringifikację obiektów w formacie JSON z odwołaniami cyklicznymi.
Alex Turpin,
7
Jezu. Powinno to być proste, oczywiste, aby móc to zrobić. Zamiast tego musimy dokonać stringifikacji, przeanalizować, zalogować i użyć specjalnej cyklicznej biblioteki referencyjnej!?! Myślę, że przeglądarki muszą lepiej radzić sobie z obsługą prostych potrzeb związanych z debugowaniem.
Mars
26

Vanilla JS:

Odpowiedź @ evan wydaje się tutaj najlepsza. Po prostu (ab) użyj JSON.parse / stringify, aby efektywnie skopiować obiekt.

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

Rozwiązanie specyficzne dla JQuery:

Możesz utworzyć migawkę obiektu w określonym momencie za pomocą jQuery.extend

console.log($.extend({}, test));

To, co się tutaj właściwie dzieje, to to, że jQuery tworzy nowy obiekt z zawartością testobiektu i rejestruje go (więc nie zmieni się).

Specyficzne rozwiązanie AngularJS (1):

Angular udostępnia copyfunkcję, której można użyć do tego samego efektu:angular.copy

console.log(angular.copy(test));

Funkcja wrappera Vanilla JS:

Oto funkcja, która zawija, console.logale tworzy kopię dowolnych obiektów przed ich wylogowaniem.

Napisałem to w odpowiedzi na kilka podobnych, ale mniej solidnych funkcji w odpowiedziach. Obsługuje wiele argumentów i nie będzie próbować kopiować rzeczy, jeśli nie są one zwykłymi obiektami.

function consoleLogWithObjectCopy () {
  var args = [].slice.call(arguments);
  var argsWithObjectCopies = args.map(copyIfRegularObject)
  return console.log.apply(console, argsWithObjectCopies)
}

function copyIfRegularObject (o) {
  const isRegularObject = typeof o === 'object' && !(o instanceof RegExp)
  return isRegularObject ? copyObject(o) : o
}

function copyObject (o) {
  return JSON.parse(JSON.stringify(o))
}

przykład użycia :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})

Zach Lysobey
źródło
6

To > Objectw konsoli nie tylko pokazuje aktualny stan. W rzeczywistości odkłada odczytanie obiektu i jego właściwości, dopóki go nie rozwiniesz.

Na przykład,

var test = {a: true}
console.log(test);
setTimeout(function () {
    test.a = false; 
    console.log(test);
}, 4000);

Następnie rozwiń pierwsze wywołanie, będzie poprawne, jeśli zrobisz to przed console.logpowrotem drugiego

Joe
źródło
2

używając wskazówki Xeon06, możesz przeanalizować jego JSON w obiekcie, a oto funkcja dziennika, której teraz używam do zrzucania moich obiektów:

function odump(o){
   console.log($.parseJSON(JSON.stringify(o)));
}
Chris
źródło
1

Zdefiniowałem narzędzie:

function MyLog(text) {
    console.log(JSON.stringify(text));
}

a kiedy chcę się zalogować do konsoli, po prostu robię:

MyLog("hello console!");

Pracuje bardzo dobrze!

Migio B
źródło
1

Istnieje możliwość użycia biblioteki debuggera.

https://debugjs.net/

Po prostu umieść skrypt na swojej stronie internetowej i umieść instrukcje dziennika.

<script src="debug.js"></script>

Logowanie

var test = {a: true}
log(test); // {a: true}
test.a = false; 
log(test); // {a: false}
Takashi Harano
źródło
0

Mogę zostać zastrzelony za zasugerowanie tego, ale można pójść o krok dalej. Możemy bezpośrednio rozszerzyć sam obiekt konsoli, aby był bardziej przejrzysty.

console.logObject = function(o) {
  (JSON.stringify(o));
}

Nie wiem, czy to spowoduje jakiś rodzaj kolizji biblioteki / rozpadu jądrowego / rozerwania w kontinuum czasoprzestrzeni. Ale działa pięknie w moich testach qUnit. :)

Dave
źródło
1
To niczego nie rejestruje. Po prostu połyka rezultat zrobienia czegoś. Zabawne, że zyskał uznanie
Zach Lysobey
0

Po prostu odśwież stronę po otwarciu konsoli lub otwórz konsolę przed przesłaniem żądania do strony docelowej ....

A. Qaoud
źródło
-1

Po prostu wydrukuj cały obiekt na konsoli.

console.dir(object);
Mangesh Bhapkar
źródło