목차
원시 타입
string number bigint boolean undefined symbol null 총 7종류가 있다.
변경 불가능한 값(immutable value)
- 변경이 불가능하다는 뜻은 메모리 영역에서의 변경이 불가능하다는 뜻이다. 재할당은 가능하다
- 변수에 할당될 때, 메모리의 고정 크기로 원시 값을 저장하고 해당 저장된 값을 변수가 직접적으로 가리키는 형태를 띈다.
- 재할당 시 기존 값이 변하는것 처럼 보일지 몰라도 사실 새로운 메모리에 재할당한 값이 저장되고 변수가 가리키는 메모리가 달라졌을 뿐이다.
예시
let a = 100;
let b = a;
a = 50;
console.log(b) // 100
즉 메모리에는 100과 50이란 값이 모두 존재하고 있으며, 앞에서 말했듯이 원시타입은 불변성을 갖고 있기 때문에 기존에 메모리에 생성된 값들은 그 자체가 변경될 수 없다. 그저 식별자와 연결 되있는 메모리가 바뀌었기에 우리 눈에는 재할당 된 것처럼 보일뿐이다.
참조형
자바스크립트에서 원시 타입 이외의 모든 값은 참조형(Reference Type) 객체(Object) 타입이며 대표적으로 배열, 함수 그리고 객체가 있다. 기본형(Primitive type)과의 차이점은 변경 가능한 값(mutable value), 즉 변수의 크기가 동적으로 변한다는 것이다.
map vs foreach
map
map()은 배열 내의 모든 요소 각각에 대하여 주어진 함수(콜백)를 호출한 결과를 모아 새로운 배열을 반환한다는 특징을 가지고 있다.
const arr = [1, 2, 3, 4, 5];
const mulArr = arr.map(num => num * 3);
console.log(arr) //[1, 2, 3, 4, 5] -> 원본 배열 영향x
console.log(mulArr); // [3, 6, 9, 12, 15]
foreach
forEach()는 문밖으로 리턴값을 받지 못한다.
let arr = [1,2,3,4,5];
let a = arr.forEach(function(value){
return value;
});
console.log(a); //undefined
-> 핵심은 forEach() 기존의 Ararry를 변경하는 반면, map()은 새로운 Ararry를 반환한다.
forEach 주의사항
원시 타입 vs 참조 타입
//원시 타입일때
let b = [1, 2, 3];
b.forEach((el) => {
el += 1; // `el`의 값은 증가하지만, 원본 배열의 요소와는 별개임
});
console.log(b); // 여전히 [1, 2, 3]
//참조 타입일때
let c = [{ value: 1 }, { value: 2 }, { value: 3 }];
c.forEach((el) => {
el.value += 1; // 객체의 속성값을 수정하면 원본 배열도 영향을 받음
});
console.log(c); // [{ value: 2 }, { value: 3 }, { value: 4 }]
slice vs splice
slice
slice() 메서드는 어떤 배열의 begin 부터 end 까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다.
let fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
let citrus = fruits.slice(1, 3);
// fruits contains ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus contains ['Orange','Lemon']
그렇다면 문자열에서는 어떨까?
문자열은 원시 타입(primitive type)으로, JavaScript에서 불변(immutable) 객체입니다. 따라서 slice를 사용할 때 원본 문자열은 전혀 변경되지 않고, 새로운 문자열을 반환한다.
let str = "Hello, World!";
let slicedStr = str.slice(0, 5);
console.log(str); // "Hello, World!"
console.log(slicedStr); // "Hello"
splice
문자열에서는 못쓰고 배열에만 사용 가능
원본 배열을 건드리기 때문에 주의 해야한다.
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// Inserts at index 1
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, 'May');
// Replaces 1 element at index 4
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "May"]
slice와 splice의 차이를 보여주는 예
> nums = Array(20).fill().map((_, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
> nums.slice(5, 8) // slice() 1회 호출
< [5, 6, 7]
> nums.slice(5, 8) // slice() 2회 호출
< [5, 6, 7]
> nums.slice(5, 8) // slice() 3회 호출
< [5, 6, 7]
> nums.slice(5, 3) // splice() 1회 호출
< [5, 6, 7]
> nums.splice(5, 3) // splice() 2회 호출
< [8, 9, 10]
> nums.splice(5, 3) // splice() 3회 호출
< [11, 12, 13]