Q: - Checkpoint의 7번 문제 복습
- pass by value: means the pointer to the value is copied into a different memory slot. so when the variable copied gets updated, it points to a new memory slot with a different primitive value.. and the other variable still points to the copied pointer to the first value
- Learning how references work
primitive vs. reference type
- primitive type: assigns a value to the variable
- reference type: assigns a reference to the address of the value to the variable
- uses storage that is dynamically changeable
- function, array, object - copies reference address, not value!
- if you assign a variable holding a primitive value to variable2, the value gets copied (pass by value). if the variable is referring to a value, it copies the reference (not the actual value; pass by reference)
primitive type
- holds one immutable value (read-only)
- 6 types (not an object, no methods):
string, number, bigint, boolean, undefined, symbol, (null)
- bigint: a number too large to be stored as a primitive
- immutability: when you reassign a value to a variable, it does not replace the one value stored in the memory the variable is pointing at, but rather the memory address the variable/identifier is pointing at, is updated to one that stores the new value
immutability of strings
- array like object: accessible like arrays, but individual elements aren't changeable like arrays
- you cannot change an individual letter within a string. you have to re-assign a different string!
- can be handled like objects! (TBC)
let str = 'string';
str.toUpperCase();
console.log(str);
str = str.toUpperCase();
console.log(str);
str[0] = 's';
console.log(str);
reference type
- mutable value
- primitive type isn't large enough to hold large arrays (more than 34 values..)
- hence, linked lists! (a pain in the ass)
- need for data type with dynamic (mutable) size
- heap: dynamic data structure without a fixed size
(this is for efficient use of memory)
pass by value
- the value (or strictly speaking, the memory address to this specific value) gets copied into a new memory slot (so changing the copied variable's value after it was copied does not change the new variable's value)
- scenario 1:
- scenario 2:
pass by reference ('call by sharing')
- js does not have pointers, so it does not pass 'references' strictly speaking
- when variables point to an object, you can change the object itself* via the variable
- multiple variables can be pointing to the same object
- objects can be huge, so
deep copy
does not make sense in efficiency. passing by reference makes more sense
let myArray = [2, 3, 4, 5];
let ourArray = myArray;
ourArray[2] = 25;
ourArray = undefined;
let x = { foo: 3 };
let y = x;
y = 2;
let player = { score: 3 };
function doStuff(obj) { obj.score = 2; }
doStuff(player);
let score = 80;
function doStuff(value) { value = 90;}
doStuff(score)
var person1 = { name: 'Lee' };
var person2 = { name: 'Lee' };
console.log(person1 === person2);
console.log(person1.name === person2.name);
shallow vs deep copy
- shallow only copies to the first level of depth (but will copy references for nested objects) whereas deep makes a full copy of the entire object (incl. nested objects)
- sometimes copying variables that store primitive values is considered 'deep' vs copying variables storing objects is considered 'shallow'
const o = { x: {y : 1} };
const c1 = {...o};
console.log(c1 === o};
console.log(c1.x === o.x);
const _ = require('lodash');
const c2 = _.cloneDeep(o);
console.log(c2 === o);
console.log(c2.x === o.x);