วิธีการโคลนวัตถุวันที่


498

การกำหนดDateตัวแปรให้กับอีกตัวแปรหนึ่งจะเป็นการคัดลอกการอ้างอิงไปยังอินสแตนซ์เดียวกัน ซึ่งหมายความว่าการเปลี่ยนจะเปลี่ยนอีกอัน

ฉันจะโคลนหรือคัดลอกDateอินสแตนซ์จริงได้อย่างไร

คำตอบ:


738

ใช้วิธีวันที่ของวัตถุgetTime()ซึ่งส่งกลับจำนวนมิลลิวินาทีตั้งแต่ 1 มกราคม 1970 00:00:00 ( เวลายุค ):

var date = new Date();
var copiedDate = new Date(date.getTime());

ใน Safari 4 คุณสามารถเขียน:

var date = new Date();
var copiedDate = new Date(date);

... แต่ฉันไม่แน่ใจว่ามันใช้งานได้ในเบราว์เซอร์อื่นหรือไม่ (ดูเหมือนว่าจะทำงานใน IE8)


9
JSON สำหรับตัวอย่างนี้ เสียงเหมือนคนเหล่านี้ควรทำให้พื้นฐานของพวกเขาชัดเจน ... เช่นการเข้าใจผิด jQuery สำหรับ JavaScript DOM
Boldewyn

17
อีกวิธีในการเขียนวิธีแก้ปัญหาที่ดีนี้คือการขยายต้นแบบวันที่: Date.prototype.clone = function() { return new Date(this.getTime()); }; ซึ่งคุณสามารถใช้เป็นcopiedDate = date.clone();
ไรอัน

6
copiedDate = new Date(date)วิธีการทำงานใน IE6 + ใน Firefox ทั้งสองตัวเลือกนั้นมีความเร็วเท่ากัน
Ryan

14
new Date(date)เช่นเดียวกับnew Date(date.getTime())เพราะ JS จะพยายามโทรdate.valueOf()เมื่อต้องการตัวเลขและdate.valueOf()เหมือนกับdate.getTime()การอ้างอิงDate.valueOf Object.valueOf
Steely Wing

10
อย่าใช้new Date(date)ใช้new Date(date.getTime()หรือnew Date(date.valueOf)แทนเนื่องจากวิธีแรกอาจทำให้เกิดความแตกต่างระหว่างวันที่อย่างน้อย Firefox และ IE (ไม่ใช่ Chrome) ยกตัวอย่างเช่นการใช้toISOString()ในวันที่ทั้งสองใน Firefox สร้างและ"2015-04-21T04:56:42.000Z" "2015-04-21T04:56:42.337Z"
crudh

114

นี่เป็นวิธีที่สะอาดที่สุด

let dat = new Date() 
let copyOf = new Date(dat.valueOf())

console.log(dat);
console.log(copyOf);


9
เมธอด "valueOf ()" สำหรับออบเจ็กต์ "Date" จะให้ผลลัพธ์เช่นเดียวกับเมธอด "getTime ()" (จำนวนมิลลิวินาทีนับตั้งแต่เวลายุค)
Steve Harrison

35
@Steve: จริง แต่ getTime () สามารถ "ดู" เหมือนว่าจะส่งคืนเวลาเท่านั้นและไม่รวมวันที่ด้วยดังนั้นการอ้างอิงของฉันถึง "cleanest" ประเภทวันที่ตรงไปตรงมาใน Javascript เป็นบิตของภัยพิบัติมันไม่ควรที่จะไม่สามารถเปลี่ยนแปลงได้ตั้งแต่แรก
AnthonyWJones

1
@AththonyWJones: ใช่ฉันเห็นสิ่งที่คุณหมายถึง
Steve Harrison

3
ฉันยอมรับว่า. valueOf () ชัดเจนยิ่งขึ้น บางครั้งฉันลืมและใช้. getMilliseconds () b / c สำหรับฉันที่ดูเหมือนว่ามันหมายถึงมิลลิวินาทีนับตั้งแต่เวลา
Tom Wayson

1
+1 ถึงสตีฟแฮร์ริสัน: ฉันสงสัยว่าเป็นเช่นนั้นหรือไม่ขอบคุณสำหรับการชี้แจง
Brian Lacy

26
var orig = new Date();
var copy = new Date(+orig);

3
ฉันชอบวิธีนี้ดีที่สุด
A1rPun

3
แม่นยำและสะอาดมาก :)
robinmitra

33
ยกเว้นคุณจะต้องอธิบายว่าเวทมนตร์+นั้นทำอะไรกับใครนอกจากผู้เชี่ยวชาญของ JS
Stijn de Witt

8
:) +เครื่องหมายเป็นผู้ดำเนินการ unaray ที่นี่ new Date( Number(orig)) มันหมายความว่า เพิ่มเติมได้ที่นี่: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

14

ฉบับย่อ:

Date.prototype.clone = function () {
    return new Date(this.getTime());
}

72
เจ้าจะไม่ยุ่งกับวัตถุในตัว
Pawel

3
คุณจะไม่ยุ่งกับวัตถุที่เจ้าไม่ได้เป็นเจ้าของ คุณควรทำสำเนาใหม่และเรียกมันว่า SuperDate หรืออะไรบางอย่างภายในขอบเขตของคุณ มีปัญหาในการทดสอบข้อบกพร่องมากมายที่เกิดจากการเปลี่ยนแปลงการทำงานของวัตถุโดยไม่คาดคิด
เรย์ฟอสส์

วิธีนี้ใช้ได้ แต่ด้วยเหตุผลด้านการบำรุงรักษาวิธีการนี้จะถือว่าเป็นกลิ่นรหัส ฉันได้เขียนวิธีการที่ฉันมักจะใช้ในการเขียนโปรแกรมของฉัน: actuts.wordpress.com/2017/01/10/…
อัลลัน Chua

1
นอกจากนี้ฉันไม่เห็นความต้องการในการพยายามเพิ่มวิธีการที่มีอยู่แล้วในตอนนี้ ศึกษาการเขียนโปรแกรมเชิงหน้าที่และค้นพบว่าทำไมฟังก์ชันสมัยเก่าที่ดีจึงมีประสิทธิภาพมากกว่าวิธีการของวัตถุ const cloneDate = d => new Date(d.getTime())นอกจากนี้ยังสั้น:
Stijn de Witt

6

ฉันพบว่างานมอบหมายที่เรียบง่ายนี้ใช้งานได้:

dateOriginal = new Date();
cloneDate = new Date(dateOriginal);

แต่ฉันไม่รู้ว่า "ปลอดภัย" ยังไง ทดสอบสำเร็จใน IE7 และ Chrome 19


9
อย่าใช้new Date(date)ใช้new Date(date.getTime()หรือnew Date(date.valueOf)แทนเนื่องจากวิธีแรกอาจทำให้เกิดความแตกต่างระหว่างวันที่อย่างน้อย Firefox และ IE (ไม่ใช่ Chrome) ยกตัวอย่างเช่นการใช้toISOString()ในวันที่ทั้งสองใน Firefox สร้างและ"2015-04-21T04:56:42.000Z" "2015-04-21T04:56:42.337Z"
crudh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.