2017-03-25 8 views
1

は、それを無効に(参照することにより)それをコピーし、私はオブジェクトを作ると言う:再割り当てが発生すると、このオブジェクトがコピーされないのはなぜですか?

let obj = { 
 
    prop: 'one' 
 
} 
 

 
let otherObj = obj 
 

 
console.log(otherObj === obj); //true 
 

 
console.log(obj.prop); //one 
 

 
obj = null; 
 

 
console.log(otherObj.prop); //shouldn't this be Uncaught TypeError: Cannot read property 'prop' of null"?

彼らは同じオブジェクトであるため、otherObjもnullではないでしょうか?

+1

いいえ、あなたは単にvarが指し示すものを変更するだけで、ターゲット自体は変更しません。オブジェクトを変更した場合は、両方の変数がそのオブジェクトを反映します。エイリアスとして2番目のvarを考える。人ではなくニックネームを削除します。 – dandavis

答えて

1

オブジェクトと、オブジェクトとそのオブジェクトの間を区別する必要があります。変数objotherObjはオブジェクトへの参照を保持するだけで、メモリ内のポインタを指します。 これらはオブジェクトのコピーではなく、同じオブジェクトではありません。それらは同じオブジェクトにポイントです。

これをより明確に説明するために、この行ごとに説明します。あなたが行うと:

let obj = { 
    prop: 'one' 
} 

をあなたはこのように、新しい参照を作成している:

enter image description here

objはただ参照と呼ばれ、オブジェクトが存在するメモリ内の場所を指しています。次に、あなたが実行します。

これに相当します
let otherObj = obj 

ここ

enter image description here

、あなたはotherObjからobj参照を割り当てます。彼らは今、お互いに完全に独立していますが、両方ともメモリ内の同じオブジェクトを参照します。 otherObjshallow copyobjの参照であるため、両方とも同じオブジェクトを参照していますが、別々です。リンクあたり:

その場合、新たなオブジェクトBが作成され、フィールド値である場合、Aのフィールドの値はB.

[...]

にコピーされますオブジェクトへの参照(例:

enter image description here

:このようなものです

obj = null 

:Aは

最後に、あなたがこれを行うんとので、同じオブジェクトを参照して、メモリアドレス)それをコピーし、参照、

objからメモリ内のオブジェクトへの参照は本質的に切断されており、今度はobj p ointsにnull、または何も。 objotherObjは互いに独立していたので、otherObjに何も起こらず、それでもメモリ内のオブジェクトを指しています。 objotherObjは別々の参照ですが、同じオブジェクトを指します。メモリ内のオブジェクトを変更すると、両方の参照に反映されますが、参照をメモリ位置に分割して参照を変更すると、他の参照は何も起こりません。

0

いいえ、新しい割り当てobj = nullを作成した瞬間に参照が失われるため、otherObjには以前の参照が含まれます。

つまり、オブジェクトの一部を変更するなど(一部のフィールドを変更するなど)、otherObjobjの両方に更新が表示されますが、そのうちの1つを再割り当てすると、メモリ内の別の場所に移動します。

0

いいえ、「参照」の概念を理解する必要がある理由を理解することはできません。

let obj = { 
    prop: 'one' 
} 

この場合、「OBJ」(メモリ位置のような)オブジェクト自体ではないが、オブジェクト「基準」である:あなたの例で

は、コードのこのビットは、オブジェクト「作成します」 - 基本的にはポインタへのポインタです。

"obj"をnullに設定する前に、SAMEオブジェクトへの参照として "otherObj"も割り当てました。この時点で2つの参照がありました。

"obj"をnullに設定すると、オブジェクトはまだ存在し、 "otherObj"によって引き続き参照されていました。少なくとももう "anotherObj"の参照がなくなるまで、メモリに保持されます。両方の参照をnullに設定すると、オブジェクト自体にアクセスできなくなり、Javscriptエンジンによって解放される可能性が高くなります。

これは非常に重要な概念です。関数に変数を渡すと、その引数はオブジェクトに対する「参照」です(本質的に不変な文字列や数値などは除きます)。変数を関数の外に再割り当てすることができ、引き数はそのまま残ります。

また、フリップサイドでは、両方の参照が同じオブジェクトを指している間に、メンバーへの変更は両方の参照に反映されます。 2つの異なるコピーが必要な場合は、オブジェクトを参照するだけでなく、オブジェクトを「クローン」するなどの作業を行う必要があります。

参照を理解することは、Javascriptでクロージャを管理する上で重要です。

0

ディープコピーとシャローコピーを区別する必要があります。あなたがやっていることは、浅いコピーと呼ばれています。ここで可視化は、次のとおりです。

シャローコピー

enter image description here enter image description here enter image description here

ディープコピー

enter image description here enter image description here enter image description here

浅いコピーの場合、両方のオブジェクト(objotherObj)は同じメモリ位置を参照します。そのため、あるオブジェクトの値を変更すると、もう一方のオブジェクトも更新されます。

一方、ディープコピーでは、各オブジェクトには独自のメモリ位置があります。あるオブジェクトの値を変更しても、他のオブジェクトの値には影響しません。

これはpostからさらに読むことができます。

-1

いいえ、変数はJavaScriptでタイプされていないためです。つまり、JavaScriptエンジンは、変数に含まれる情報から変数の型を判断できます。 Visual Basicでは、非常によく似た種類の変数が"variant"と呼ばれています。

ですから、objは、オブジェクト値をある

let otherObj = obj; 

を言うならば、あなたは今、彼らはオブジェクトである知っているし、(オブジェクトが参照として実装されているかに行かなくても)同じオブジェクト値を持つ2つの変数を持っています。

あなたが今

obj = null; 

を実行するのであればobjの値が(ちなみに一つの値のみサポートするデータ型の「ヌル」、持っている:ヌル)の値nullで上書きされています。

明らかに、1つの変数に新しい値を割り当てることは、別の変数に保持されている値を変更することはできません。プログラミング言語はこれに依存します。

objの値が更新された後、otherObjには以前と同じオブジェクト値が含まれています。値が「1」のプロパティ「prop」を持つオブジェクトです。

関連する問題