Primitive vs. Reference Types + Immutability (D13)

devfish·2023년 1월 2일


목록 보기

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(); //'STRING'
console.log(str); //'string'

str = str.toUpperCase(); 
console.log(str); //'STRING'

str[0] = 's';
console.log(str); //'STRING'

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;

//myArray -> [2, 3, 25, 5]
//ourArray는 undefined로 재할당되었기 때문에 myArray에 접근할 수 없음

let x = { foo: 3 };
let y = x;
y = 2;

// -> 3
//y는 원시자료형을 재할당받음. = 2면 바뀌었겠지만..

let player = { score: 3 };
function doStuff(obj) {  obj.score = 2; }

//player.score = 2; 
//obj & player points to the same address when the function is called 

let score = 80;
function doStuff(value) { value = 90;}
//score = 80
//the variable score's value is copied within the function
//not the address score points to!

//comparing objects
var person1 = { name: 'Lee' }; 
var person2 = { name: 'Lee' };

console.log(person1 === person2); //false. returns different reference values!
console.log( ===; //true. these are comparing expressions that are evaluated as values 

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} }; 
//shallow copy
const c1 = {...o}; 
console.log(c1 === o}; //false
console.log(c1.x === o.x); //true

//deep copy
//lodash- cloneDeep - "npm install lodash" -> run in node
const _ = require('lodash'); 
const c2 = _.cloneDeep(o); 
console.log(c2 === o); //false
console.log(c2.x === o.x); //false
la, di, lah

0개의 댓글