Jak sklonować obiekt Date?

498

Przypisanie Datezmiennej do innej spowoduje skopiowanie odwołania do tego samego wystąpienia. Oznacza to, że zmiana jednego zmieni drugie.

Jak mogę faktycznie sklonować lub skopiować Dateinstancję?

Árvíztűrő tükörfúrógép
źródło

Odpowiedzi:

738

Użyj metody obiektu DategetTime() , która zwraca liczbę milisekund od 1 stycznia 1970 r. 00:00:00 ( czas epoki ):

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

W Safari 4 możesz także napisać:

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

... ale nie jestem pewien, czy to działa w innych przeglądarkach. (Wydaje się, że działa w IE8).

Steve Harrison
źródło
9
JSON dla tego fragmentu? Wygląda na to, że ci ludzie powinni wyjaśnić swoje podstawy ... Jak pomylić jQuery z JavaScript DOM.
Boldewyn
17
Innym sposobem na napisanie tego miłego rozwiązania byłoby rozszerzenie prototypu Data: Date.prototype.clone = function() { return new Date(this.getTime()); }; którego można następnie użyć jakocopiedDate = date.clone();
Ryan
6
copiedDate = new Date(date)Podejście działa w IE6 +. W przeglądarce Firefox dwie opcje mają tę samą prędkość.
Ryan
14
new Date(date)to samo new Date(date.getTime()), ponieważ JS spróbuje zadzwonić, date.valueOf()gdy będzie potrzebować numeru, i date.valueOf()jest taki sam jak date.getTime()odnośnik Date.valueOf Object.valueOf
Steely Wing
10
Nie używaj new Date(date), używaj new Date(date.getTime()lub new Date(date.valueOf)zamiast tego, ponieważ pierwszy sposób może prowadzić do różnic między datami przynajmniej w przeglądarce Firefox i IE (nie w Chrome). Na przykład używanie toISOString()w obu datach w przeglądarce Firefox generuje "2015-04-21T04:56:42.000Z"i "2015-04-21T04:56:42.337Z".
crudh
114

To jest najczystsze podejście

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

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

AnthonyWJones
źródło
9
Metoda „valueOf ()” dla obiektów „Date” daje taki sam wynik jak metoda „getTime ()” (liczba milisekund od czasu epoki).
Steve Harrison
35
@Steve: true, ale getTime () może „wyglądać”, jakby zwracał tylko godzinę i nie zawierał również daty, stąd moje odniesienie do „najczystszego”. Szczerze mówiąc, data w JavaScript jest trochę strefą katastrofy, nigdy nie powinna być zmienna.
AnthonyWJones
1
@AnthonyWJones: Tak, rozumiem, co masz na myśli.
Steve Harrison
3
Zgadzam się, że .valueOf () jest bardziej przejrzysty. Czasami zapominam i używam .getMilliseconds () b / c dla mnie, co brzmi jak oznacza milisekundy od epoki.
Tom Wayson,
1
+1 do Steve'a Harrisona: Zastanawiałem się, czy tak było, dzięki za wyjaśnienie.
Brian Lacy
26
var orig = new Date();
var copy = new Date(+orig);
Dave
źródło
3
Najbardziej podoba mi się to rozwiązanie.
A1rPun
3
Bardzo precyzyjnie i czysto :)
robinmitra 26.09.16
33
Tyle że będziesz musiał wyjaśnić, co ta magia +robi każdemu oprócz ekspertów JS.
Stijn de Witt
8
:) +znak jest tutaj nierealnym operatorem. Oznacza to new Date( Number(orig)) . Więcej tutaj: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Leonard Lepadatu
14

Wersja uproszczona:

Date.prototype.clone = function () {
    return new Date(this.getTime());
}
Bereż
źródło
72
nie będziesz bałaganu z wbudowanymi obiektami
Paweł
3
Nie będziesz bałaganu z przedmiotami, których nie posiadasz. Powinieneś zrobić nową kopię i nazwać ją SuperDate lub coś w tym zakresie. Wiele trudnych do przetestowania błędów jest spowodowanych niespodziewaną zmianą funkcjonalności obiektu.
Ray Foss,
To działałoby, ale z powodów związanych z utrzymaniem, takie podejście byłoby uważane za zapach kodu. Napisałem podejście, którego zwykle używam do kodowania: actuts.wordpress.com/2017/01/10/…
Allan Chua
1
Nie widzę też potrzeby dodawania metod do wbudowanych funkcji. Studiuj programowanie funkcjonalne i dowiedz się, dlaczego dobra, staromodna funkcja jest w rzeczywistości znacznie potężniejsza niż metody na samym obiekcie. Jest to także krótszy: const cloneDate = d => new Date(d.getTime()).
Stijn de Witt
6

Dowiedziałem się, że to proste przypisanie działa również:

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

Ale nie wiem, jak to jest „bezpieczne”. Pomyślnie przetestowany w IE7 i Chrome 19.

LK
źródło
9
Nie używaj new Date(date), używaj new Date(date.getTime()lub new Date(date.valueOf)zamiast tego, ponieważ pierwszy sposób może prowadzić do różnic między datami przynajmniej w przeglądarce Firefox i IE (nie w Chrome). Na przykład używanie toISOString()w obu datach w przeglądarce Firefox generuje "2015-04-21T04:56:42.000Z"i "2015-04-21T04:56:42.337Z".
crudh