JavaScript Copy by Reference
JavaScript is a versatile language with various data types, including primitive and reference types. Understanding how these types are copied is crucial for effective programming. In this article, we'll delve into the world of JavaScript copy by reference, exploring the differences between primitive and reference types, shallow and deep copying, and providing practical tips for working with these concepts.
Primitive Types
Primitive types in JavaScript are values stored directly in variables. When you copy a primitive value, it creates a new copy of the value in a new memory space.
- Examples:
string
,number
,boolean
,undefined
,null
,symbol
,bigint
let a = 10;
let b = a; // a's value is copied to b
b = 20; // only b is changed
console.log(a); // 10
console.log(b); // 20
- Here,
a
andb
have independent values. - Although
a
's value is copied tob
, they occupy different memory spaces. Therefore, changingb
doesn't affecta
.
Reference Types
Reference types in JavaScript store the reference address of an object in variables. When you copy an object or array, you're copying the reference address, not the value. This means both variables will point to the same object.
- Examples:
object
,array
,function
,date
,regExp
,map
,set
let person1 = {
name: 'John',
age: 30
};
let person2 = person1; // person1's reference address is copied to person2
person2.age = 35; // person2's age value is changed
console.log(person1.age); // 35 (person1 is also changed)
console.log(person2.age); // 35
-
person1
andperson2
point to the same object. Changingperson2
affectsperson1
because they reference the same memory space.
Characteristics of Copy by Reference
- Both variables point to the same object, so changing one affects the other.
- No new object is created when copying arrays or objects; only the reference address is copied.
Shallow Copy
When copying reference types, we use the concept of shallow copying. Shallow copying only copies the top-level properties of an object and copies the reference to inner objects or arrays.
Shallow Copy Example
let original = {
name: 'Alice',
hobbies: ['reading', 'biking']
};
let copy = { ...original }; // shallow copy using spread operator
copy.name = 'Bob'; // only the copy is changed
copy.hobbies.push('swimming'); // both the original and copy are changed
console.log(original.name); // Alice (unchanged)
console.log(original.hobbies); // ['reading', 'biking', 'swimming']
console.log(copy.hobbies); // ['reading', 'biking', 'swimming']
- Changing
name
only affects the copy, but both the original and copy share the samehobbies
array.
Deep Copy
Deep copying creates a completely independent object by copying all nested objects and arrays. This solves the reference problem that can occur with shallow copying.
Deep Copy Example
- Using
JSON.parse()
andJSON.stringify()
for deep copying
let original = {
name: 'Alice',
hobbies: ['reading', 'biking']
};
let copy = JSON.parse(JSON.stringify(original)); // deep copy
copy.name = 'Bob'; // only the copy is changed
copy.hobbies.push('swimming'); // only the copy is changed
console.log(original.name); // Alice (unchanged)
console.log(original.hobbies); // ['reading', 'biking']
console.log(copy.hobbies); // ['reading', 'biking', 'swimming']
-
JSON.parse(JSON.stringify())
creates a new copy of the object, including all nested objects and arrays, solving the reference issue.
Alternative Methods
- Using the
cloneDeep()
function from thelodash
library for deep copying
const _ = require('lodash');
let copy = _.cloneDeep(original);
- This method is particularly useful when dealing with complex, nested objects.
In conclusion, understanding how JavaScript copies values, whether by reference or by value, is essential for writing effective and bug-free code. By recognizing the differences between primitive and reference types and knowing when to use shallow or deep copying, you can better manage your data and avoid common pitfalls. Remember, the key to mastering JavaScript is practice and a deep understanding of its fundamental concepts.
Top comments (0)