Làm cách nào tôi có thể tạo console.log hiển thị trạng thái hiện tại của một đối tượng?


146

Trong Safari không có tiện ích bổ sung (và thực tế là hầu hết các trình duyệt khác), console.logsẽ hiển thị đối tượng ở trạng thái thực thi cuối cùng, không phải ở trạng thái khi console.logđược gọi.

Tôi phải sao chép đối tượng chỉ để xuất nó thông qua console.logđể có được trạng thái của đối tượng tại dòng đó.

Thí dụ:

var test = {a: true}
console.log(test); // {a: false}
test.a = false; 
console.log(test); // {a: false}

2
ví dụ jsfiddle về vấn đề và các giải pháp khác nhau được đưa ra dưới đây: jsfiddle.net/luken/M6295
Luke

7
Nó là cực kỳ trực quan cho chức năng đăng nhập để xuất một tham chiếu trực tiếp đến đối tượng. Đó được gọi là đồng hồ , khác nhiều so với một mục nhật ký. Sẽ không có ý nghĩa gì hơn khi làm điều này khi ghi nhật ký một đối tượng so với khi ghi nhật ký một biến lưu trữ giá trị nguyên thủy.
ngất xỉu

2
Làm thế nào tôi chưa bao giờ một số trên này trước đây? Tôi thấy điều này thật đáng sợ
ErikAGriffin

Câu trả lời:


171

Tôi nghĩ rằng bạn đang tìm kiếm console.dir().

console.log()không làm những gì bạn muốn bởi vì nó in một tham chiếu đến đối tượng và khi bạn mở nó ra, nó đã thay đổi. console.dirin một thư mục của các thuộc tính trong đối tượng tại thời điểm bạn gọi nó.

Ý tưởng JSON dưới đây là một ý tưởng hay; thậm chí bạn có thể tiếp tục phân tích chuỗi JSON và nhận một đối tượng có thể duyệt được như những gì .dir () sẽ cung cấp cho bạn:

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


38
Đối với tôi trong Chrome13, không có sự khác biệt giữa console.logconsole.dir
Andrew D.

Hừm, thật đáng ngạc nhiên - nó hoạt động trong Fireorms. Tôi đã nghĩ rằng nó là giống nhau trong Webkit.
evan

1
Điều tôi thấy trong Chrome là nếu bạn mở bảng điều khiển sau khi câu lệnh đăng nhập chạy, thì nó sẽ thực hiện đánh giá lười biếng khi bạn mở rộng nó. Nhưng nếu bảng điều khiển đã mở (ví dụ: bạn mở bàn điều khiển và sau đó nhấn refresh trên trang), nó sẽ đánh giá háo hức - tức là in giá trị tại thời điểm câu lệnh log được chạy.
Polemarch

6
Ngoài ra, thư mục là JSON như bản sao nông là sao chép sâu. console.dir () sẽ chỉ đánh giá các thuộc tính của đối tượng cấp cao nhất (các đối tượng lồng nhau sâu hơn khác sẽ không được đánh giá), trong khi JSON sẽ đi theo cách đệ quy.
Polemarch

9
Tương tự như vậy đối với tôi console.dirkhông hoạt động trong Chrome (v33). Dưới đây là so sánh các giải pháp mà mọi người đã đưa ra: jsfiddle.net/luken/M6295
Luke

71

Những gì tôi thường làm nếu tôi muốn thấy trạng thái của nó tại thời điểm nó được ghi lại là tôi chỉ cần chuyển đổi nó thành một chuỗi JSON.

console.log(JSON.stringify(a));

4
Thật tuyệt, đó là một gợi ý hay cho tôi: tôi chỉ cần phân tích lại một lần nữa để có đối tượng của mình ngay trong bảng điều khiển. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris

1
cảm ơn việc này cho tôi console.dir đã không in nó
ah-shiang han

1
Điều gì xảy ra nếu đối tượng của bạn có chứa cấu trúc vòng tròn?
Alex McMillan

1
@AlexMcMillan Bạn có thể sử dụng một trong một số thư viện cho phép xâu chuỗi JSON các đối tượng với các tham chiếu vòng tròn.
Alex Turpin

7
Trời ạ. Đây phải là một điều đơn giản, rõ ràng để có thể làm. Thay vào đó chúng ta phải xâu chuỗi, phân tích, ghi nhật ký và sử dụng một thư viện tham chiếu hình tròn đặc biệt!?! Tôi nghĩ rằng các trình duyệt cần phải làm tốt hơn việc hỗ trợ các nhu cầu gỡ lỗi đơn giản.
Sao Hỏa

26

Vanilla JS:

Câu trả lời của @ evan có vẻ tốt nhất ở đây. Chỉ cần (ab) sử dụng JSON.parse / stringify để tạo một bản sao của đối tượng một cách hiệu quả.

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

Giải pháp cụ thể của JQuery:

Bạn có thể tạo ảnh chụp nhanh của một đối tượng tại một thời điểm nhất định với jQuery.extend

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

Điều thực sự xảy ra ở đây là jQuery đang tạo một đối tượng mới với testnội dung của đối tượng và ghi nhật ký đó (vì vậy nó sẽ không thay đổi).

Giải pháp cụ thể của AngularJS (1):

Angular cung cấp một copychức năng có thể được sử dụng cho cùng một hiệu ứng:angular.copy

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

Hàm bao bọc Vanilla JS:

Đây là một chức năng bao bọc console.lognhưng sẽ tạo một bản sao của bất kỳ đối tượng nào trước khi đăng xuất chúng.

Tôi đã viết điều này để đáp lại một vài chức năng tương tự nhưng kém mạnh mẽ hơn trong các câu trả lời. Nó hỗ trợ nhiều đối số và sẽ không cố sao chép mọi thứ nếu chúng không phải là đối tượng thông thường .

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))
}

sử dụng ví dụ :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})


6

Trong > Objectbảng điều khiển, không chỉ hiển thị trạng thái hiện tại. Nó thực sự đang trì hoãn việc đọc đối tượng và thuộc tính của nó cho đến khi bạn mở rộng nó.

Ví dụ,

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

Sau đó mở rộng cuộc gọi đầu tiên, nó sẽ chính xác, nếu bạn thực hiện trước khi cuộc gọi thứ hai console.logtrở lại


2

sử dụng gợi ý của Xeon06, bạn có thể phân tích JSON của anh ấy trong một đối tượng và đây là chức năng nhật ký mà tôi hiện đang sử dụng để kết xuất các đối tượng của mình:

function odump(o){
   console.log($.parseJSON(JSON.stringify(o)));
}

1

Tôi đã xác định một tiện ích:

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

và khi tôi muốn đăng nhập vào giao diện điều khiển, tôi chỉ cần làm:

MyLog("hello console!");

Nó hoạt động rất tốt!



1

Có một tùy chọn để sử dụng thư viện trình gỡ lỗi.

https://debugjs.net/

Chỉ cần đưa tập lệnh vào trang web của bạn và đặt báo cáo nhật ký.

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

Ghi nhật ký

var test = {a: true}
log(test); // {a: true}
test.a = false; 
log(test); // {a: false}

0

Tôi có thể bị bắn vì đã gợi ý điều này, nhưng điều này có thể tiến thêm một bước nữa. Chúng ta có thể trực tiếp mở rộng đối tượng giao diện điều khiển để làm cho nó rõ ràng hơn.

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

Tôi không biết nếu điều này sẽ gây ra một số loại va chạm thư viện / sự tan vỡ hạt nhân / rip trong liên tục không thời gian. Nhưng nó hoạt động rất đẹp trong các bài kiểm tra qUnit của tôi. :)


1
Điều này không đăng nhập bất cứ điều gì. Nó chỉ nuốt kết quả của việc xâu chuỗi một cái gì đó.
Thật

0

Chỉ cần làm mới trang sau khi bạn mở bảng điều khiển hoặc mở bảng điều khiển trước khi bạn gửi yêu cầu đến trang được nhắm mục tiêu ....


-1

Chỉ cần in toàn bộ đối tượng trên bàn điều khiển.

console.dir(object);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.