[javascript] Copy a variable's value into another

I have a variable which has a JSON object as its value. I directly assign this variable to some other variable so that they share the same value. This is how it works:

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

This works and both have the same value. I use a mousemove event handler to update b through out my app. On a button click, I want to revert b to the original value, meaning the value stored in a.

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

After this if I use the same mousemove event handler, it updates both a and b, when earlier it was updating only b as expected.

I'm stumped over this issue! What is wrong here?

This question is related to javascript jquery

The answer is


For strings or input values you could simply use this:

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

A solution for AngularJS:

$scope.targetObject = angular.copy($scope.sourceObject)

the question is already solved since quite a long time, but for future reference a possible solution is

b = a.slice(0);

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


The reason for this is simple. JavaScript uses refereces, so when you assign b = a you are assigning a reference to b thus when updating a you are also updating b

I found this on stackoverflow and will help prevent things like this in the future by just calling this method if you want to do a deep copy of an 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.");
}

I found using JSON works but watch our for circular references

var newInstance = JSON.parse(JSON.stringify(firstInstance));

I do not understand why the answers are so complex. In Javascript, primitives (strings, numbers, etc) are passed by value, and copied. Objects, including arrays, are passed by reference. In any case, assignment of a new value or object reference to '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; a.a = 'c'; // b.a === 'c' and a.a === 'c'

Paste any of the above lines (one at a time) into node or any browser javascript console. Then type any variable and the console will show it's value.


Most of the answers here are using built-in methods or using libraries/frameworks. This simple method should work fine:

function copy(x) {
    return JSON.parse( JSON.stringify(x) );
}

// Usage
var a = 'some';
var b = copy(a);
a += 'thing';

console.log(b); // "some"

var c = { x: 1 };
var d = copy(c);
c.x = 2;

console.log(d); // { x: 1 }

I solved it myself for the time being. The original value has only 2 sub-properties. I reformed a new object with the properties from a and then assigned it to b. Now my event handler updates only b, and my original a stays 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 };
});

This works fine. I have not changed a single line anywhere in my code except for the above, and it works just how I wanted it to. So, trust me, nothing else was updating a.


newVariable = originalVariable.valueOf();

for objects you can use, b = Object.assign({},a);