Як клонувати об’єкт Date?


498

Призначення Dateзмінної іншої копіює посилання на той самий екземпляр. Це означає, що зміна одного змінить інше.

Як я можу фактично клонувати або копіювати Dateекземпляр?

Відповіді:


738

Використовуйте метод об'єкта DategetTime() , який повертає кількість мілісекунд з 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 два варіанти мають однакову швидкість.
Райан

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 ()" для об'єктів "Дата" дає такий же результат, як і його метод "getTime ()" (кількість мілісекунд з часу епохи).
Стів Харрісон

35
@Steve: правда, але getTime () може "виглядати" так, що він тільки повертає час, а не включає дату, а отже, моє посилання на "найчистіший". Відверто кажучи, тип дати в Javascript - це трохи зона катастроф, вона ніколи не повинна була змінюватися в першу чергу.
AnthonyWJones

1
@AnthonyWJones: Правильно, я бачу, що ти маєш на увазі.
Стів Харрісон

3
Я згоден, що .valueOf () більш зрозумілий. Іноді я забуваю і використовую .getMilliseconds () b / c для мене, що звучить так, що це означає середні мілісекунди з часу епохи.
Том Уейсон

1
+1 Стіву Харрісону: Мені було цікаво, чи це було так, дякую за уточнення.
Брайан Лейсі

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

3
Мені подобається це рішення найкраще.
A1rPun

3
Дуже точний і чистий :)
robinmitra

33
За винятком того, що вам доведеться пояснювати, що ця магія +робить будь-кому, крім експертів JS.
Штійн де Вітт

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
не будеш возитися із вбудованими предметами
Павло

3
Не будеш возитися з предметами, якими ти не володієш. Вам слід створити нову копію і назвати її SuperDate або щось подібне, не враховуючи сферу застосування. Багато клопотів, які важко перевірити на помилки, викликані несподіваною зміною функціональності об'єкта.
Рей Фосс

Це спрацювало б, але з міркувань ремонту цей підхід розглядався б як кодовий запах. Я написав підхід, який зазвичай використовую у своєму кодуванні: actuts.wordpress.com/2017/01/10/…
Аллан Чуа

1
Також я не бачу в цьому потреби в спробі додати методи до вбудованих програм в першу чергу. Вивчіть функціональне програмування та з’ясуйте, чому хороша старомодна функція насправді набагато потужніша, ніж методи на самому об’єкті. Це також коротше: const cloneDate = d => new Date(d.getTime()).
Штійн де Вітт

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.