0

さまざまなj/scriptネイティブ日付オブジェクトメソッドを使用して日付オブジェクトを更新しようとしていますが、変更がページ上のすべての日付オブジェクトに適用されているように見える理由がわかりません。

私は当初、日付のプロトタイプにメソッドを追加することを推奨する投稿を見つけましたが、これによりすべての日付オブジェクトが変更されました。次に簡略化したところ、両方の日付がまだ更新されていることがわかりました。これを防ぐ方法についてアドバイスをいただければ幸いです。私が欲しいのは、このように少し見えるものを介したstarTimeとendTimeです。(注:最終的には関数になります)。

time1 = new Date();
alert(time1);//returns Sat May 26 11:15:41 EDT 2012
time2=time1;
time2.setMinutes(time2.getMinutes()+10);
alert(time1); //returns Sat May 26 11:25:41 EDT 2012
alert(time2);//returns Sat May 26 11:25:41 EDT 20112  

質問:date2のみを更新するのに、なぜdate2=date1なのですか。

4

3 に答える 3

5

これを行うとき:

time2=time1;

...新しい Dateオブジェクトを作成するのではなく、2つの別々の変数から日付オブジェクトを指しているだけです。オブジェクトは1つしかないため、どの変数を調べても、当然、オブジェクトに加えた変更はすべて明らかです。

それにASCIIアートを投げましょう:

time1 = new Date();

それは私たちに与えます:

+ ------- +
+ time1 +
+ ------- + + --------------- +
| 値|---------------->| Dateオブジェクト|
+ ------- + + --------------- +

今あなたがするとき:

time2=time1;

我々は持っています

+ ------- +
+ time1 |
+ ------- +
| 値|------+
+ ------- + | + --------------- +
               + ---------> | Dateオブジェクト|
               | + --------------- +
+ ------- + |
+ time2 | |
+ ------- + |
| 値|------+
+ ------- +

and変数のはオブジェクトへの参照であり、オブジェクトのコピーではありません。(すべてのオブジェクトはこのように機能します。)オブジェクト参照は、メモリ内のオブジェクトを見つける場所のメモリアドレスのようなものと考えることができます。(実際の内容は実装によって異なります。)time1time2Date

これは、変数の値に実際にプリミティブのデータが含まれているプリミティブとは異なります。例

var n = 42;

結果は

+ ----------- +
+ n |
+ ----------- +
| 値:42 |
+ ----------- +

理論的には、文字列「プリミティブ」はそれが真実であるかのように動作しますが、実際にはおそらくオブジェクトのように格納されます。問題ではありません。文字列は不変で==あり===、文字列プリミティブの場合はコンテンツを比較するため、できません。違いを実際に伝えて、それらが実際に変数に含まれているように見せかけることができます。[本当に混乱するだけです。JavaScriptにはNumberString オブジェクトのように動作するオブジェクトもあります。])


以下の質問を再確認してください。

暫定的に、既存のオブジェクトと同一の2番目のjavascriptオブジェクトを作成する最も効率的な方法は何ですか?

JavaScriptオブジェクトには一般的な「クローン」操作がないため、答えはオブジェクトによって異なります。一部のオブジェクトは、不変(変更できない)であり、クローンを作成する必要がないため(Stringたとえば、オブジェクト)、クローンを作成する必要はありません。

日付のクローンを作成するには、簡単です。

time2 = new Date(time1);

または、もう少し効率的です。

time2 = new Date(+time1);

+time1オブジェクトにそれ自体を数値に変換するように指示し、Dateコンストラクターはその数値を使用するためです。これがないと、time1オブジェクトはそれ自体を文字列に変換するように求められ、Dateコンストラクターはその文字列を解析します。それでも機能しますが、数字を介して、マイクロでほぼ確実に時期尚早の最適化であり、エンジンが使用したい隠れた最適化を妨げる可能性がありますtime2 = new Date(time1);

于 2012-05-26T15:21:57.877 に答える
1

これまでに投稿された2つの 答えは正しいです。解決策は、最初の日付からコピーされた、同じ内部ミリ秒値を使用する2番目の日付を作成することです。

var time1 = new Date();
var time2 = new Date(time1.getTime());

これで、互いに独立して操作できる2つの異なる日付インスタンスができました

var time1 = new Date();
alert(time1); // Sat May 26 2012 11:26:16 GMT-0400 (EDT)
var time2 = new Date(time1.getTime());
time2.setMinutes(time2.getMinutes()+10);
alert(time1); // Sat May 26 2012 11:26:16 GMT-0400 (EDT)
alert(time2); // Sat May 26 2012 11:36:16 GMT-0400 (EDT)

詳細:日付–MDN

于 2012-05-26T15:25:15.767 に答える
0

これを行うとき:

time1 = new Date();  // <-- creates a new Date object
time2 = time1;       // <-- time2 gets passed a reference to the time1 object
                     //     making them effectively the same

最初の行でDateオブジェクトを作成しますが、2番目の行は別のDateオブジェクトを作成せ、すでに作成されたDateオブジェクトをポイントまたは参照するだけです。これは、多くのオブジェクト指向プログラミング言語に共通の機能です。

于 2012-05-26T15:22:58.630 に答える