Copy variable value to another

I have a variable that has a JSON object as a value. I directly assign this variable to some other variable so that they have the same value. Here's how it works:

var a = $('#some_hidden_var').val(), b = a; 

This works, and both have the same meaning. I am using the mousemove event mousemove to update b through my application. When I click the button, I want to return b to the original value, that is, the value stored in a .

 $('#revert').on('click', function(e){ b = a; }); 

After that, if I use the same mousemove event mousemove , it updates both a and b , when before it only updated b , as expected.

I exaggerate this problem! What is wrong here?

+56
javascript jquery
Sep 16 '13 at 13:21
source share
8 answers

It is important to understand what the = operator does in JavaScript and does not.

The = operator does not copy data.

The = operator creates a new link to the same data.

After running the source code:

 var a = $('#some_hidden_var').val(), b = a; 

a and b now two different names for the same object.

Any changes you make to the contents of this object will be displayed the same way, whether you refer to it using variable a or variable b . This is the same object.

So, when you later try to โ€œreturnโ€ b to the original object a with this code:

 b = a; 

The code actually does nothing, because a and b are the same. The code is the same as if you wrote:

 b = b; 

which obviously won't do anything.

Why is your new code working?

 b = { key1: a.key1, key2: a.key2 }; 

Here you create a new object with the object literal {...} . This new object does not match your old object. That way, you now set b as a reference to this new object, which does what you want.

To process any arbitrary object, you can use the function to clone the object, for example, specified in Armand's answer, or, since you are using jQuery, just use the $.extend() function . This function will make either a shallow copy or a deep copy of the object. (Do not confuse this with the $().clone() method, which is designed to copy DOM elements, not objects.)

For a shallow copy:

 b = $.extend( {}, a ); 

Or a deep copy:

 b = $.extend( true, {}, a ); 

What is the difference between a shallow copy and a deep copy? A shallow copy is similar to your code that creates a new object with an object literal. It creates a new top-level object containing references to the same properties as the original object.

If your object contains only primitive types, such as numbers and strings, deep copy and shallow copy will do the same. But if your object contains other objects or arrays nested inside it, then a shallow copy does not copy these nested objects, but simply creates links to them. Thus, you may have the same problem with nested objects that you had with your top-level object. For example, given this object:

 var obj = { w: 123, x: { y: 456, z: 789 } }; 

If you make a shallow copy of this object, then the x property of your new object will be the same x object from the original:

 var copy = $.extend( {}, obj ); copy.w = 321; copy.xy = 654; 

Now your objects will look like this:

 // copy looks as expected var copy = { w: 321, x: { y: 654, z: 789 } }; // But changing copy.xy also changed obj.xy! var obj = { w: 123, // changing copy.w didn't affect obj.w x: { y: 654, // changing copy.xy also changed obj.xy z: 789 } }; 

You can avoid this with a deep copy. A deep copy is repeated in all nested objects and arrays (and Date in the Armand code) to make copies of these objects in the same way that they made a copy of the top-level object. Therefore, changing copy.xy will not affect obj.xy

Short answer: if in doubt, you probably want to get a deep copy.

+129
Sep 17 '13 at 7:19
source share

I found use of JSON works, but I look at our round links

 var newInstance = JSON.parse(JSON.stringify(firstInstance)); 
+30
Mar 17 '15 at 10:04
source share

the issue has already been resolved for quite some time, but for a future reference, a possible solution is

 b = a.slice(0); 

Be careful, this only works correctly if a is a non-nested array of numbers and strings

+11
Feb 13 '14 at 17:24
source share

The reason is simple. JavaScript uses a referee, so when you assign b = a , you assign a reference to b , so when you update a you also update b

I found this one on stackoverflow and will help prevent similar things in the future, just calling this method if you want to make a deep copy of the object.

 function clone(obj) { // Handle the 3 simple types, and null or undefined if (null == obj || "object" != typeof obj) return obj; // Handle Date if (obj instanceof Date) { var copy = new Date(); copy.setTime(obj.getTime()); return copy; } // Handle Array if (obj instanceof Array) { var copy = []; for (var i = 0, len = obj.length; i < len; i++) { copy[i] = clone(obj[i]); } return copy; } // Handle Object if (obj instanceof Object) { var copy = {}; for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]); } return copy; } throw new Error("Unable to copy obj! Its type isn't supported."); } 
+9
Sep 17 '13 at 7:19
source share

For strings or input values, you can simply use this:

 var a = $('#some_hidden_var').val(), b = a.substr(0); 
+4
Jan 08 '16 at 8:03
source share

I donโ€™t understand why the answers are so complicated. In Javascript, primitives (strings, numbers, etc.) are passed by value and copied. Objects, including arrays, are passed by reference. In any case, assigning a new value or a reference to object "a" will not change "b". But changing the contents of a will change the contents of b.

 var a = 'a'; var b = a; a = 'c'; // b === 'a' var a = {a:'a'}; var b = a; a = {c:'c'}; // b === {a:'a'} and a = {c:'c'} var a = {a:'a'}; var b = a; aa = 'c'; // ba === 'c' and aa === 'c' 

Paste any of the above lines (one at a time) into node or any browser javascript console. Then enter any variable and the console will display its value.

+2
Dec 25 '16 at 7:15
source share

I have decided it myself so far. The initial value has only 2 sub-properties. I converted a new object with properties from a and then assigned it to b . Now my event handler is updated only b , and my original a remains as it is.

 var a = { key1: 'value1', key2: 'value2' }, b = a; $('#revert').on('click', function(e){ //FAIL! b = a; //WIN b = { key1: a.key1, key2: a.key2 }; }); 

It works great. I have not changed a single line in my code except the above, and it works the way I wanted it. So, believe me, nothing else was updated a .

0
Sep 17 '13 at 7:03
source share

newVariable = originalVariable.valueOf ()

-one
Oct 24 '17 at 13:06 on
source share



All Articles