ฉันจะทำให้ console.log แสดงสถานะปัจจุบันของวัตถุได้อย่างไร


146

ใน Safari ที่ไม่มีส่วนเสริม (และเบราว์เซอร์อื่น ๆ ส่วนใหญ่) console.logจะแสดงวัตถุที่สถานะสุดท้ายของการดำเนินการไม่ใช่ที่สถานะเมื่อconsole.logถูกเรียก

ฉันต้องโคลนวัตถุเพื่อเอาท์พุทผ่านconsole.logเพื่อให้ได้สถานะของวัตถุที่บรรทัดนั้น

ตัวอย่าง:

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

2
ตัวอย่าง jsfiddle ของปัญหาและวิธีแก้ปัญหาต่าง ๆ ที่ได้รับด้านล่าง: jsfiddle.net/luken/M6295
ลุค

7
มันเป็นเรื่องที่ใช้ง่ายมากสำหรับฟังก์ชั่นบันทึกการส่งออกอ้างอิงสดไปยังวัตถุ ที่เรียกว่านาฬิกาซึ่งแตกต่างจากรายการบันทึกมาก มันไม่มีเหตุผลที่จะทำสิ่งนี้อีกต่อไปเมื่อทำการบันทึกวัตถุมากกว่าเมื่อทำการบันทึกตัวแปรที่เก็บค่าดั้งเดิม
faintsignal

2
ฉันไม่เคยเจอเรื่องแบบนี้มาก่อนเลยเหรอ? ฉันพบสิ่งที่น่ากลัวนี้
ErikAGriffin

คำตอบ:


172

console.dir()ผมคิดว่าคุณกำลังมองหา

console.log()ไม่ได้ทำสิ่งที่คุณต้องการเพราะมันพิมพ์การอ้างอิงไปยังวัตถุและเมื่อคุณเปิดมันขึ้นมามันก็เปลี่ยนไป console.dirพิมพ์ไดเรกทอรีของคุณสมบัติในวัตถุในเวลาที่คุณเรียกมัน

แนวคิด JSON ด้านล่างเป็นแนวคิดที่ดี คุณยังสามารถแยกวิเคราะห์สตริง JSON และรับวัตถุที่สามารถเรียกดูได้เช่นสิ่งที่. dir () จะให้:

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


38
สำหรับฉันใน Chrome13 ไม่มีความแตกต่างระหว่างconsole.logและconsole.dir
Andrew D.

หืมมันน่าประหลาดใจ - มันใช้งานได้ใน Firebug ฉันคิดว่ามันเหมือนกันใน Webkit
evan

1
สิ่งที่ฉันเห็นใน Chrome คือถ้าคุณเปิดคอนโซลหลังจากที่คำสั่งบันทึกทำงานแล้วมันจะทำการประเมินผลที่ขี้เกียจเมื่อคุณขยาย แต่ถ้าคอนโซลเปิดอยู่แล้ว (เช่นคุณเปิดคอนโซลแล้วกดรีเฟรชบนหน้า) มันจะทำการประเมินผลที่กระตือรือร้น - เช่นพิมพ์ค่าในเวลาที่คำสั่งบันทึกถูกเรียกใช้
Polemarch

6
นอกจากนี้ dir คือ JSON เนื่องจากการคัดลอกตื้นจะเป็นการคัดลอกลึก console.dir () จะประเมินคุณสมบัติของวัตถุระดับบนสุดเท่านั้น (วัตถุที่ซ้อนกันที่ลึกกว่านั้นจะไม่ถูกประเมิน) ในขณะที่ JSON จะทำงานซ้ำ ๆ
Polemarch

9
เช่นเดียวกันสำหรับฉันconsole.dirไม่ทำงานใน Chrome (v33) นี่คือการเปรียบเทียบโซลูชันที่ผู้คนนำเสนอ: jsfiddle.net/luken/M6295
ลุค

71

สิ่งที่ฉันมักจะทำถ้าฉันต้องการที่จะเห็นว่ามันเป็นสถานะในเวลาที่มันถูกบันทึกไว้ฉันเพียงแค่แปลงเป็นสตริง JSON

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

4
เยี่ยมมากนั่นเป็นคำใบ้ที่ดีสำหรับฉัน: ฉันต้องแยกมันอีกครั้งเพื่อให้วัตถุของฉันอยู่ในคอนโซล function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris

1
ขอบคุณมันใช้งานได้สำหรับฉัน! console.dir ไม่ได้พิมพ์
ah-shiang han

1
เกิดอะไรขึ้นถ้าวัตถุของคุณมีโครงสร้างแบบวงกลม
Alex McMillan

1
@AlexMcMillan คุณสามารถใช้หนึ่ง ใน หลาย ๆไลบรารีที่อนุญาตให้ใช้การทำให้เป็นสตริง JSON ของวัตถุที่มีการอ้างอิงแบบวงกลม
Alex Turpin

7
โธ่ สิ่งนี้ควรเป็นสิ่งที่ง่ายและชัดเจนที่สามารถทำได้ แต่เราต้องทำให้สตริงแยกวิเคราะห์บันทึกและใช้ไลบรารีอ้างอิงแบบวงกลมพิเศษ! ฉันคิดว่าเบราว์เซอร์ต้องทำงานได้ดีขึ้นในการรองรับความต้องการการดีบักอย่างง่าย
ดาวอังคาร

26

วานิลลา JS:

คำตอบของ @ evanดูดีที่สุดที่นี่ Just (ab) ใช้ JSON.parse / stringify เพื่อทำสำเนาของวัตถุอย่างมีประสิทธิภาพ

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

โซลูชั่นเฉพาะของ JQuery:

คุณสามารถสร้างสแน็ปช็อตของวัตถุ ณ เวลาใดเวลาหนึ่งด้วย jQuery.extend

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

สิ่งที่เกิดขึ้นจริงที่นี่คือ jQuery กำลังสร้างวัตถุใหม่ที่มีtestเนื้อหาของวัตถุและบันทึกว่า (ดังนั้นจะไม่เปลี่ยนแปลง)

โซลูชั่นเฉพาะของ AngularJS (1):

Angular จัดให้มีcopyฟังก์ชันที่สามารถใช้เอฟเฟกต์เดียวกันได้:angular.copy

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

ฟังก์ชั่น wrapper วานิลลา JS:

นี่คือฟังก์ชันที่ล้อมรอบconsole.logแต่จะทำสำเนาของวัตถุใด ๆ ก่อนออกจากระบบ

ฉันเขียนสิ่งนี้เพื่อตอบสนองต่อฟังก์ชั่นที่คล้ายกัน แต่มีประสิทธิภาพน้อยกว่าในคำตอบ รองรับหลายอาร์กิวเมนต์และจะไม่พยายามคัดลอกสิ่งต่าง ๆ หากไม่ใช่วัตถุปกติ

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

ตัวอย่างการใช้งาน :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})


6

ที่> Objectอยู่ในคอนโซลไม่เพียงแสดงสถานะปัจจุบัน อันที่จริงมันเป็นการชะลอการอ่านวัตถุและคุณสมบัติของมันจนกว่าคุณจะขยาย

ตัวอย่างเช่น,

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

จากนั้นขยายสายแรกมันจะถูกต้องหากคุณทำก่อนที่console.logจะส่งกลับที่สอง


2

ด้วยการใช้คำใบ้ของ Xeon06 คุณสามารถแยก JSON ของเขาในวัตถุและนี่คือฟังก์ชั่นบันทึกที่ฉันใช้ในการถ่ายโอนวัตถุของฉัน:

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

1

ฉันกำหนดโปรแกรมอรรถประโยชน์:

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

และเมื่อฉันต้องการเข้าสู่ระบบคอนโซลฉันก็ทำ:

MyLog("hello console!");

มันใช้งานได้ดีมาก!



1

มีตัวเลือกให้ใช้ไลบรารีดีบักเกอร์

https://debugjs.net/

เพียงรวมสคริปต์ไว้ในหน้าเว็บของคุณและใส่คำสั่งบันทึก

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

เข้าสู่ระบบ

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

0

ฉันอาจถูกยิงเพราะแนะนำสิ่งนี้ แต่สามารถดำเนินการต่อไปอีกขั้นหนึ่ง เราสามารถขยายวัตถุคอนโซลโดยตรงเพื่อทำให้ชัดเจนยิ่งขึ้น

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

ฉันไม่รู้ว่าสิ่งนี้จะทำให้เกิดการปะทะกันของห้องสมุด / นิวเคลียร์หลอมละลาย / ฉีกขาดในอวกาศอย่างต่อเนื่องหรือไม่ แต่มันทำงานได้อย่างสวยงามในการทดสอบ qUnit ของฉัน :)


1
นี่ไม่ได้บันทึกอะไรเลย มันกลืนผลของการทำให้บางสิ่งบางอย่างเป็นก้อน ตลกที่มันได้คะแนนมาก
Zach Lysobey

0

เพียงรีเฟรชหน้าเว็บหลังจากที่คุณเปิดคอนโซลหรือเปิดคอนโซลก่อนที่คุณจะส่งคำขอไปยังหน้าเป้าหมาย ...


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.