PROGRAMMING-CONCEPTS

Memory and References: Definition, Purpose, and Examples

Memory and references describe how data is stored, shared, and copied at runtime. Understanding these mechanics helps you avoid accidental mutations, bugs caused by shared references, and performance issues, especially when working with arrays, objects, and large data structures.

While immutability focuses on design philosophy (“don’t change values in place”), memory and references explain the real behavior underneath your code.


Value Types vs Reference Types

Value Types

A value type stores the actual data. When you copy it, you get a completely separate value.

Reference Types

A reference type stores a pointer to the data. When you copy it, you copy the reference, not the data itself, so different variables may point to the same underlying object.


Value Types in Action

JavaScript (primitives are value types)

let a = 10;
let b = a;
b = 20;

Changing b doesn’t affect a because numbers are value types. Each variable holds its own independent copy.

Python (ints, floats, bools are value-like)

x = 5
y = x
y = 9

Assigning y to x copies the value. Updating y doesn’t change x.

Swift (structs, enums are value types)

struct Point { var x: Int; var y: Int }
var p1 = Point(x: 1, y: 2)
var p2 = p1
p2.x = 9

Changing p2 does not change p1 because Swift structs are copied on assignment.


Reference Types in Action

JavaScript (objects and arrays)

const original = { score: 10 };
const copy = original;
copy.score = 50;

Modifying copy also changes original because both variables refer to the same object. This is why object-related bugs often surprise beginners.

Python (lists, dicts)

data = {"count": 1}
alias = data
alias["count"] = 3

Changing alias affects data since they point to the same dictionary. Python treats these containers as references.

Swift (classes)

class Person { var age: Int; init(age: Int) { self.age = age } }
let p1 = Person(age: 20)
let p2 = p1
p2.age = 40

Swift classes behave like reference types, so updating p2 also updates p1.


Pass by Value vs Pass by Reference

JavaScript

JavaScript always passes values, but when the value is a reference, the function receives the reference itself.

function update(obj) {
  obj.count = 99;
}

const item = { count: 1 };
update(item);

The function updates the original object because the reference itself is passed as the value. This explains why parameter changes can affect the caller.

Python

Python passes object references by value (a hybrid model).

def modify(lst):
    lst.append(4)

numbers = [1, 2, 3]
modify(numbers)

The list is updated because the reference points to the same underlying data. However, reassigning the variable inside the function does not affect the original reference.

Swift

Swift uses copy-on-write for value types and reference semantics for classes.

func add(_ array: inout [Int]) {
    array.append(5)
}

var nums = [1, 2]
add(&nums)

Passing with inout allows mutation of the original variable, otherwise Swift normally copies value types.


Shallow Copy vs Deep Copy

A shallow copy creates a new container but keeps references to the same inner values.

A deep copy duplicates the entire structure, including nested data.


Shallow Copy Example (JavaScript)

const original = { stats: { score: 10 } };
const shallow = { ...original };
shallow.stats.score = 99;

The nested object is still shared, so updating the inner value changes both objects. Shallow copies don’t protect you from changes inside nested structures.


Deep Copy Example (JavaScript)

const original = { stats: { score: 10 } };
const deep = JSON.parse(JSON.stringify(original));
deep.stats.score = 50;

This creates a fully independent copy, so modifying deep does not affect original. It’s a simple deep copy method for data without functions or special types.


Python: Shallow vs Deep Copy

import copy

a = {"info": {"level": 1}}
shallow = copy.copy(a)
deep = copy.deepcopy(a)

copy.copy keeps nested references, while copy.deepcopy duplicates everything. This distinction matters when working with complex dictionaries or lists.


Swift: Structs Short-Circuit the Problem

Swift structs automatically copy deeply because they’re value types.

struct Score { var high: Int }
var s1 = Score(high: 10)
var s2 = s1
s2.high = 30

No shared memory exists between s1 and s2, so Swift avoids accidental mutations by default.


Memory Leaks

A memory leak happens when memory is allocated but never released because something keeps referencing it. Over time, this can slow down or crash your program.

JavaScript: Leaks Through Unncessary Long-Lived References

let cache = {};

function add(id, data) {
  cache[id] = data; // never removed
}

The cache object grows forever unless entries are removed. Large web apps must carefully manage references inside closures and event listeners.


Swift: Strong Reference Cycles

class A { var b: B? }
class B { var a: A? }

Both objects point to each other strongly, so neither is released. Swift solves this with weak or unowned references.


Python: Reference Cycles

a = {}
b = {}
a["b"] = b
b["a"] = a

These circular references won't be freed until the garbage collector runs. Large cycles can accumulate and create slowdowns in long-running programs.


When Memory and References Matter

  • when you pass arrays or objects into functions and see unexpected changes
  • when you clone or merge nested data structures
  • when React state updates accidentally mutate existing values
  • when working with APIs returning deeply nested JSON
  • when debugging performance issues in Swift classes or Python objects
  • when managing large caches, listeners, or long-lived objects in JavaScript

Understanding these mechanics helps you predict how your data behaves as your program grows more complex.


Summary

Memory and references explain why some variables behave independently and others unexpectedly affect each other. Value types store data directly, reference types point to shared memory, shallow copies duplicate outer structures while sharing inner ones, and deep copies fully separate data. Concepts like pass-by-value, pass-by-reference, and memory leaks all stem from these mechanics, and mastering them helps you write safer, more predictable code.

Learn to Code for Free
Start learning now
button icon
To advance beyond this tutorial and learn tocode by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

Reach your coding goals faster