When an object is assigned to a variable, will modifying the variable modify the original object?

This is similar to the previous blog post except this is more direct. The answer is “Yes” for all tested languages except C and C++.

This may seem trivial until you meet a situation where the same original object is shared across requests/sessions, like a public static variable in Java or an incorrectly scoped Javascript variable used in a NodeJS application (read StackOverflow post on Why do different node.js sessions share variables?).

A request may modify/overwrite the original object (e.g. a lookup array) and mess things up for subsequent requests. In the case of Javascript, instead of doing var myVariable = someObject;, it would be safer to clone the object, e.g. using a shallow copy var myVariable = Object.assign({}, someObject);. However, shallow copies will only work for the first/top level of properties – problems will still exist for nested properties which are copied by reference. For creating deep copies, read this article on 3 Ways to clone objects in JavaScript.

Below are sample code snippets for each language tested, with the output commented at the end of the sample code. Languages tested (in alphabetical order of file extension): C, C++, Java, Javascript, PHP, Python, Swift.

C
Ans: No

/**
 * test.c
 *
 * To run:
 *   gcc test.c -o a.out
 *   ./a.out
 */

#include <stdio.h>

struct MyClass {
    int myProperty;
};

int main()
{
    int originalPrimitive = 1;
    int newPrimitive = originalPrimitive;
    printf("originalPrimitive: %d\n", originalPrimitive);
    newPrimitive = 2;
    printf("originalPrimitive: %d\n", originalPrimitive);
    printf("\n");

    struct MyClass originalObject;
    originalObject.myProperty = 1;
    struct MyClass newObject = originalObject;
    printf("originalObject.myProperty: %d\n", originalObject.myProperty);
    newObject.myProperty = 2;
    printf("originalObject.myProperty: %d\n", originalObject.myProperty);

    return 0;
}

/* Output:
originalPrimitive: 1
originalPrimitive: 1

originalObject.myProperty: 1
originalObject.myProperty: 1
*/

C++
Ans: No

/**
 * test.cpp
 *
 * To run:
 *   gcc test.cpp -o a.out
 *   ./a.out
 */

#include <stdio.h>

class MyClass {
    public:
        int myProperty;
};

int main()
{
    int originalPrimitive = 1;
    int newPrimitive = originalPrimitive;
    printf("originalPrimitive: %d\n", originalPrimitive);
    newPrimitive = 2;
    printf("originalPrimitive: %d\n", originalPrimitive);
    printf("\n");

    MyClass originalObject;
    originalObject.myProperty = 1;
    MyClass newObject = originalObject;
    printf("originalObject.myProperty: %d\n", originalObject.myProperty);
    newObject.myProperty = 2;
    printf("originalObject.myProperty: %d\n", originalObject.myProperty);

    return 0;
}

/* Output:
originalPrimitive: 1
originalPrimitive: 1

originalObject.myProperty: 1
originalObject.myProperty: 1
*/

Java
Ans: Yes

/**
 * test.java
 *
 * To run:
 *     javac test.java
 *     java main
 */

import java.io.*;

class MyClass
{
    public int myProperty;
}

class main
{
    public static void main(String[] args) throws Exception
    {
        int originalPrimitive = 1;
        int newPrimitive = originalPrimitive;
        System.out.printf("originalPrimitive: %d\n", originalPrimitive);
        newPrimitive = 2;
        System.out.printf("originalPrimitive: %d\n", originalPrimitive);
        System.out.printf("\n");

        MyClass originalObject = new MyClass();
        originalObject.myProperty = 1;
        MyClass newObject = originalObject;
        System.out.printf("originalObject.myProperty: %d\n", originalObject.myProperty);
        newObject.myProperty = 2;
        System.out.printf("originalObject.myProperty: %d\n", originalObject.myProperty);
    }
}

/* Output:
originalPrimitive: 1
originalPrimitive: 1

originalObject.myProperty: 1
originalObject.myProperty: 2
*/

Javascript
Ans: Yes

/**
 * test.js
 *
 * To run:
 *   node test.js
 */

var originalPrimitive = 1;
var newPrimitive = originalPrimitive;
console.log("originalPrimitive: ", originalPrimitive);
newPrimitive = 2;
console.log("originalPrimitive: ", originalPrimitive);
console.log("");

// Doesn't matter if declared using const - myProperty can still be changed
var originalObject = {
    myProperty: 1
};
var newObject = originalObject;
console.log("originalObject.myProperty: ", originalObject.myProperty);
newObject.myProperty = 2;
console.log("originalObject.myProperty: ", originalObject.myProperty);

/* Output:
originalPrimitive:  1
originalPrimitive:  1

originalObject.myProperty:  1
originalObject.myProperty:  2
*/

PHP
Ans: Yes

<?php
/**
 * test.php
 *
 * To run:
 *   php test.php
 */

class MyClass
{
    public $myProperty;
}

$originalPrimitive = 1;
$newPrimitive = $originalPrimitive;
printf("originalPrimitive: %d\n", $originalPrimitive);
$newPrimitive = 2;
printf("originalPrimitive: %d\n", $originalPrimitive);
printf("\n");

$originalObject = new MyClass();
$originalObject->myProperty = 1;
$newObject = $originalObject;
printf("originalObject.myProperty: %d\n", $originalObject->myProperty);
$newObject->myProperty = 2;
printf("originalObject.myProperty: %d\n", $originalObject->myProperty);

/* Output:
originalPrimitive: 1
originalPrimitive: 1

originalObject.myProperty: 1
originalObject.myProperty: 2
*/

Python
Ans: Yes

"""
test.py

To run:
  python test.py
  python3 test.py
"""

class MyClass:
    myProperty = 0

originalPrimitive = 1
newPrimitive = originalPrimitive
print("originalPrimitive: {}".format(originalPrimitive))
newPrimitive = 2
print("originalPrimitive: {}".format(originalPrimitive))
print("")

originalObject = MyClass()
originalObject.myProperty = 1
newObject = originalObject
print("originalObject.myProperty: {}".format(originalObject.myProperty))
newObject.myProperty = 2
print("originalObject.myProperty: {}".format(originalObject.myProperty))

""" Output (both Python 2 & Python 3):
originalPrimitive: 1
originalPrimitive: 1

originalObject.myProperty: 1
originalObject.myProperty: 2
"""

Swift
Ans: Yes

/**
 * test.swift
 *
 * To run:
 *   swift test.swift
 */

class MyClass {
    public var myProperty: Int = 0
}

var originalPrimitive: Int = 1
var newPrimitive: Int = originalPrimitive
print("originalPrimitive: \(originalPrimitive)")
newPrimitive = 2
print("originalPrimitive: \(originalPrimitive)")
print("")

var originalObject: MyClass = MyClass()
originalObject.myProperty = 1
var newObject = originalObject
print("originalObject.myProperty: \(originalObject.myProperty)")
newObject.myProperty = 2
print("originalObject.myProperty: \(originalObject.myProperty)")

/* Output:
originalPrimitive: 1
originalPrimitive: 1

originalObject.myProperty: 1
originalObject.myProperty: 2
*/