
화살표 함수의 축약형
x => x * 1
위의 코드와 아래 코드는 똑같은 표현
x => {
return x * 1;
}
중괄호 {} 없이 한 줄로 쓰면 자동으로 return이 포함된다
그러나, 중괄호를 쓰면 명시적 return이 필요함!
const arr2 = arr.map((x) => {
x * 1; // 이건 return 없기 때문에 결과는 [undefined, undefined, undefined]
});
이렇게 쓰면 아무 값도 반환하지 않기 때문에 undefined만 들어간다
const a = ['1', '2'].map(x => x * 1); // [1, 2]
const b = ['1', '2'].map(x => { return x * 1 }); // [1, 2]
const c = ['1', '2'].map(x => { x * 1 }); // [undefined, undefined]
//명시적 변환
Number("123abc"); // NaN ❌ 전체 문자열 숫자여야 함
Number.parseInt("123abc") // 123 ⭕ 앞에 숫자만 읽음
Number("3.14") // 3.14 ⭕ 실수 OK
Number.parseInt("3.14") // 3 ❗ 소수점 이후는 잘림
Number(" 42 "); // 42 ⭕ 양 끝 공백 무시
Number.parseInt(" 42 ") // 42 ⭕ 양 끝 공백 무시
parseInt()는 문자열을 왼쪽부터 숫자로 해석하려 시도, 숫자 부분까지만 해석
숫자가 아닌 문자가 맨 앞에 오면, 숫자 해석을 전혀 못하므로 NaN을 반환
| 입력값 | 결과 | 설명 |
|---|---|---|
| 'a' | NaN | 숫자로 시작 안 하므로 변환 불가 |
| '123abc' | 123 | 숫자 부분까지만 해석 |
| 'abc123' | NaN | 맨 앞이 숫자 아님 |
| '3.14' | 3 | parseInt는 소수점 무시 |
// 암묵적 변환
num = str * 1;
num = +str;
자바스크립트의 자동 형 변환을 이용한 방법
* 연산자는 피연산자 중 하나라도 숫자가 아니면 숫자로 변환하려고 시도
Number(str)와 동일한 효과
단항 더하기 연산자
피연산자 하나를 숫자로 변환하려고 시도하는 연산자
+피연산자 이렇게 쓰면 자바스크립트는 해당 피연산자를 숫자로 변환하려고 함.
- 단항 : 피연산자가 하나만 있는 연산자
- + : 덧셈이 아니라 변환의 의미
+"42" // 42 (문자열 -> 숫자) +"-7.5" // -7.5 +true // 1 +false // 0 +null // 0 +undefined // NaN +"hello" // NaN (문자열이 숫자가 아님)
let num = 123;
let str = num.toString(); // "123"
❌ 원본을 변경하지 않음 ❌
let str = 'abcd';
let arr = str.split('');
console.log(arr); // [ 'a', 'b', 'c', 'd']
str = "ab cd"
arr = str.split(' ')
console.log(arr); // [ 'ab', 'cd']
const example = 'VITA - C';
const [word, alpha] = example.split(' - ');
console.log(word); // VITA
console.log(alpha); // C
const s = "pyelp";
const result = s.split(/[py]/); // 'p' 또는 'y'를 구분자로 사용
console.log(result); // ["", "", "el", ""]
❌ 원본을 변경하지 않음 ❌
스프레드 문법 : iterable(반복 가능한) 객체를 펼치는 것
iterable한 객체 : 문자열, 배열, Set, Map, arguments
iterable하지 않은 객체 : 정수(Number), 일반 객체 ({})
const str = "abcd";
const arr = [...str];
console.log(arr); // [ 'a', 'b', 'c', 'd' ]
const arr = [3, 1, 4];
Math.min(...arr); // 1
const a = [1, 2, 3];
const b = [...a]; // b는 a의 복사본
const a = [1, 2];
const b = [3, 4];
const combined = [...a, ...b]; // [1, 2, 3, 4]
str.split('')와 비슷한 역할을 함.
(단, split('')은 문자열 전용이고 ...는 더 범용적)
ES2018부터 객체의 프로퍼티(key-value)를 펼치는 기능이 별도로 추가되어, 이제 객체에도 스프레드 문법을 쓸 수 있게 되었다.
객체가 가진 자신의 프로퍼티(속성, key-value 쌍) 들을 펼쳐서 다른 객체에 복사하거나 합치는 역할을 함.
const obj1 = {
a: 1, b: 2
};
const copiedObj = { ...obj1 }; // obj1의 프로퍼티들을 펼쳐서 새 객체를 만듦
console.log(copiedObj); // { a: 1, b: 2 }
console.log(obj1 === copiedObj); // false (새로운 객체이므로 주소값이 다름)
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 }; // b라는 키가 겹침
const mergedObj = { ...obj1, ...obj2 }; // obj1을 펼치고, 그 위에 obj2를 덮어씀
console.log(mergedObj); // { a: 1, b: 3, c: 4 } (뒤에 오는 값으로 덮어써짐)
❌ 원본을 변경하지 않음 ❌
반환값이 반드시 필요함
const newArray = arr.map((element, index, array) => {
// return 값이 새로운 배열의 요소가 됨
});
- element: 현재 요소
- index (선택): 현재 요소의 인덱스
- array (선택): 원본 배열 전체
const arr = ['1', '2', '3'];
const arr2 = arr.map(x => x * 1); // 또는 Number(x)
console.log(arr2); // [1, 2, 3]
const names = ["cat", "dog", "rabbit"];
const labeled = names.map((name, index) => `${index + 1}번 ${name}`);
console.log(labeled); // ["1번 cat", "2번 dog", "3번 rabbit"]
const arr = [5, 10, 15, 20];
const result = arr
.map((item, index) => ({ item, index })) // 요소와 인덱스를 객체로 묶고
.filter(({ item }) => item > 12); // 조건 필터링은 요소로
result.forEach(({ item, index }) => {
console.log(`조건 만족: 값 = ${item}, 인덱스 = ${index}`);
});
/*
조건 만족: 값 = 15, 인덱스 = 2
조건 만족: 값 = 20, 인덱스 = 3
*/
const arr = [10, 20, 30, 40];
const result = arr
.map((value, index) => ({ value, index })) // 객체로 value + index 묶기
.find(({ value }) => value >= 25); // 조건 체크는 value 기준으로
console.log(result); // { value: 30, index: 2 }
arr.reduce((accumulator, currentValue, index, array) => {
return 누산할_값;
}, 초기값);
- accumulator (acc) 누적된 값 (초기에는 초기값)
- currentValue (cur) 현재 순회 중인 배열 요소
- index (선택) 현재 인덱스
- array (선택) 원본 배열 전체
- initialValue 처음 acc에 들어갈 값 (생략 가능)
const arr = [1, 2, 3, 4];
const sum = arr.reduce((acc, cur) => acc + cur, 0);
// 1+2+3+4 = 10
console.log(sum); // 10
- 1회: acc = 0, cur = 1 → 반환 1
- 2회: acc = 1, cur = 2 → 반환 3
- 3회: acc = 3, cur = 3 → 반환 6
- 4회: acc = 6, cur = 4 → 반환 10
const arr = [3, 7, 2, 9];
const max = arr.reduce((acc, cur) => (cur > acc ? cur : acc));
console.log(max); // 9
const arr = ['H', 'e', 'l', 'l', 'o'];
const word = arr.reduce((acc, cur) => acc + cur, '');
console.log(word); // "Hello"
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana'];
const count = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(count);
// { apple: 2, banana: 2, orange: 1 }
❓여기서는 왜 acc이 ket-value쌍의 객체를 저장하고있을까❓
initialValue, 즉 초기값으로 {} 객체를 주었기 때문이다! (객체는 항상 key-value 쌍의 집합)
| 메서드 | 설명 |
|---|---|
Object.keys(obj) | 키 배열 반환 |
Object.values(obj) | 값 배열 반환 |
Object.entries(obj) | [키, 값] 쌍 배열 반환 |
Object.fromEntries(arr) | 배열 → 객체 |
Object.hasOwn(obj, key) | 직접 소유 여부 확인 |
Object.assign() | 객체 복사/병합 |
Object.freeze() | 완전 불변 |
Object.seal() | 수정만 가능 |
Object.is() | 정밀 비교 (NaN, -0) |
주의! 순서를 항상 보장하지 않을수도 있다.
요즘 대부분의 JS 엔진은 삽입 순서대로 출력
하지만! Object는 명확하게 순서를 보장하지는 않음
특히 숫자형 키를 쓰면 순서가 자동 정렬되기도 함const obj = {}; obj[2] = 'two'; obj[1] = 'one'; console.log(obj); // { '1': 'one', '2': 'two' } ← 숫자 키는 정렬됨!
Object.keys()가 반환한 배열도 반환 순서는 기본적으로 삽입된 순서지만, 숫자 문자열(key가 '1', '2' 같은 경우)은 정렬되기 때문에 주의가 필요.
만약 순서를 보장하고싶다면 Map 사용을 권장.
- Map은 입력한 순서를 반드시 유지
- 숫자 키를 써도 절대 정렬되지 않음
const person = {
name: 'Alice',
age: 30
};
- name이 key, 'Alice'가 value
- age가 key, 30이 value
즉, 객체는 이렇게 생긴 쌍을 여러 개 담고 있는 자료구조
아래의 객체는 숫자 형태의 문자열 키("32", "36" 등)와 숫자 값을 가진다.
자바스크립트 객체는 key를 자동으로 문자열로 변환하기 때문에, 숫자처럼 보여도 실제로는 문자열 key이다!
const obj = {
32: 10,
36: 6,
48: 26
};
우리가 원하는 key를 동적으로 추가해서 사용할 수 있다.
const obj = {};
obj["fruit"] = "apple"; // { fruit: "apple" }
obj["count"] = 3; // { fruit: "apple", count: 3 }
delete obj["fruit"]; //삭제 되면 true, 아니면 false
Object.entries(dic)
Object.keys(dic);
Object.values(dic)
Object.keys(info).length;
for (let [key, value] of Object.entries(info)) {
console.log(key, value);
}
obj[key]는 key가 키로 존재하면 값(value)를 반환하고, 존재하지 않으면 undefined를 반환
자바스크립트에서 undefined는 Falsy 값이라 조건문에서 false로 평가된다.
const obj = { 32: 10, 36: 6 };
let key = 32;
//key가 존재하면 if블록 실행, 존재하지 않으면 else블록 실행
if (obj[key]) {
...
} else {
...
}
console.log(obj[key]); // 10
console.log(obj["32"]); // 10
console.log(obj[32]); // 10
객체의
키는 항상문자열이기 때문에,
obj[32] -> 실제로는 obj["32"]와 같음
obj.e와 obj[e]는 다르다!
const obj = {}; return [...s].map((e, i) => { let result = obj[e] !== undefined ? i - obj[e] : -1; obj[e] = i; return result; });obj.e는 항상 obj["e"]를 의미한다. 즉, 문자 'e'라는 속성에 접근하게 됨.
e는 s의 각 문자(예: 'a', 'b', 'c' 등) 이다.
따라서 우리가 원하는 의도대로 실행하려면?
obj[e]를 사용하여 obj['a'], obj['b'], ... 처럼 동적으로 접근해야 합니다.
key in dict
let dict = {
fruits: ["apple", "banana", "cherry"]
};
let key = "fruits";
if (key in dict) {
let fruitsArray = dict[key];
console.log("과일 목록:", fruitsArray); // 과일 목록: [ 'apple', 'banana', 'cherry' ]
}
배열로 펼친후에 정렬을 수행해야함!
let dict = {
a: [5, 2],
b: [3, 1],
c: [7, 0]
};
// value의 첫 번째 요소(인덱스 0) 기준으로 정렬
// 배열로 펼친후에 정렬을 수행해야함!
let sorted = Object.entries(dict).sort((a, b) => a[1][0] - b[1][0]);
console.log(sorted);
/*
[
['b', [3, 1]],
['a', [5, 2]],
['c', [7, 0]]
]
*/
//다시 객체로 변경
let sortedDict = Object.fromEntries(sorted);
console.log(sortedDict);
/*
{
b: [3, 1],
a: [5, 2],
c: [7, 0]
}
*/
‼️⭕ 원본 배열 자체를 변경 ⭕‼️하고 뒤집힌 배열을 반환
let n = 12345;
let arr = n.toString().split('').reverse();
console.log(arr); // [ '5', '4', '3', '2', '1' ]
❌ 원본을 변경하지 않음 ❌
join()은 요소를 쉼표(,)로 이어붙이기 때문에 구분자를 주지않으면 문자 사이에 ,가 포함된다.
let arr = [ '5', '4', '3', '2', '1' ];
let basic = arr.join();
console.log(basic); // 5,4,3,2,1
let str = arr.join('');
console.log(str); // 54321
let apple = arr.join(' 🍎 ');
console.log(apple); // 5 🍎 4 🍎 3 🍎 2 🍎 1
str.match(regexp)
/패턴/옵션 형태)옵션 종류
g: 전부 찾기 (global)
i: 대소문자 무시 (ignore case)
const str = "apple banana";
const result = str.match(/a/);
console.log(result);
/*
[
'a', // 일치한 문자
index: 0, // 위치
input: 'apple banana', // 원본 문자열
groups: undefined
]
*/
const str = "apple banana";
const result = str.match(/a/g);
console.log(result); // ['a', 'a', 'a', 'a']
const str = "Pineapple";
const result = str.match(/p/gi);
console.log(result); // ['P', 'p', 'p']
p와 y의 갯수를 각각 구해보자
let s = "paskypsYfsPp"
const countP = (s.match(/p/gi) || []).length;
const countY = (s.match(/y/gi) || []).length;
console.log(countP); // 4
console.log(countY); // 2
🔍 왜 || []를 사용하는가?
match()는 일치하는 게 없으면 null을 반환함 -> null.length를 바로 쓰면 에러발생
에러 방지를 위해 || []를 써서 null일 경우 빈 배열로 대체해줌
let s = "paskypsYfsPp"
let countP = s.split(/[pP]/).length - 1;
let countY = s.split(/[yY]/).length - 1;
console.log(countP); // 4
console.log(countY); // 2
‼️⭕ 원본 배열 자체를 변경 ⭕‼️
const arr = ['banana', 'apple', 'cherry'];
arr.sort();
console.log(arr); // ["apple", "banana", "cherry"]
const arr = ['banana', 'apple', 'cherry'];
arr.sort().reverse();
console.log(arr); // ["cherry", "banana", "apple"]
숫자를 그대로 sort() 하면 의도한 대로 오름차순 정렬이 되지 않음.
const arr = [1, 4, 10, 21, 2];
arr.sort();
console.log(arr); // [1, 10, 2, 21, 4] ❌
따라서 아래처럼 정렬해줘야함!
1. 오름차순
let arr = [1, 4, 10, 21, 2];
arr.sort((a,b) => a - b);
console.log(arr); // [ 1, 2, 4, 10, 21 ]
let arr = [1, 4, 10, 21, 2];
arr.sort((a,b) => b - a);
console.log(arr); // [ 21, 10, 4, 2, 1 ]
| 함수 | 설명 |
|---|---|
| Math.sqrt(x) | x의 제곱근 |
| Math.pow(x, y) | x의 y제곱 |
| Math.abs(x) | 절댓값 |
| Math.floor(x) | 내림 |
| Math.ceil(x) | 올림 |
| Math.round(x) | 반올림 |
| 함수 | 설명 |
|---|---|
| Number.isInteger(value) | 정수인지 확인 |
| Number.isNaN(value) | 값이 NaN인지 확인(isNaN()과는 다르게 타입 검사도 정확히 함) |
| Number.isFinite(value) | 값이 유한한 숫자인지 확인 (Infinity, NaN 제외) |
| Number.parseInt(str, [radix]) | 문자열을 정수로 파싱 |
| Number.parseFloat(str) | 문자열을 실수로 파싱 |
| Number.MAX_VALUE | 자바스크립트에서 표현 가능한 가장 큰 수 |
| Number.MIN_VALUE | 0에 가장 가까운 양수 (가장 작은 수 아님) |
string.includes(searchString, position)
true 또는 falseconst str = "Hello, world!";
console.log(str.includes("world")); // true
console.log(str.includes("World")); // false (대소문자 구분)
console.log(str.includes("world", 8)); // false (8번째 인덱스부터 찾음)
array.includes(searchElement, fromIndex)
const fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("banana")); // true
console.log(fruits.includes("grape")); // false
console.log(fruits.includes("apple", 1)); // false
str.toLowerCase().includes("hello".toLowerCase())
const arr = ["Apple", "Banana", "Cherry"];
const target = "banana";
const found = arr.some(item => item.toLowerCase() === target.toLowerCase());
console.log(found); // true
const arr = ["Samsung Electronics", "LG Display", "SK Hynix"];
const keyword = "display";
// 대소문자 무시 + 부분 포함
const result = arr.some(item => item.toLowerCase().includes(keyword.toLowerCase()));
console.log(result); // true
하나라도 있으면 true를 반환, 없으면 false 반환
array.some(callback(element, index, array), thisArg)
const numbers = [1, 3, 5, 6];
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true
배열의 모든 요소가 조건을 만족하면 true
하나라도 만족하지 않으면 false
array.every(callback(element, index, array), thisArg)
const numbers = [1, 3, 5];
const allPositive = numbers.every(num => num > 0);
console.log(allPositive); // true (전부 양수)
const brands = ["Samsung", "Sony", "LG"];
const allStartWithUpper = brands.every(b => b[0] === b[0].toUpperCase());
console.log(allStartWithUpper); // true
기본적인 논리 연산의 용도 if (x > 0 && x < 10)로도 여전히 잘 쓰이고 있음.
그저 추가적으로 조건식 외부에서도 쓸 수 있다는 것이 JavaScript의 확장된 개념
A && B A가 falsy면 A를 반환하고, A가 truthy면 B를 반환
즉, 왼쪽이 false면 오른쪽을 평가하지 않고 바로 반환(short-curcuit evaluation 단축평가)
true && "Hello" // "Hello"
false && "Hello" // false
0 && "Hello" // 0
"Hi" && 123 // 123
조건이 참일때만 실행하고 싶을 때
o % divisor === 0 && answer.push(o)
앞의 조건이 true일때만 뒤를 실행
A가 truthy면 A를 바로 반환 (B는 평가하지 않음 —> 단축 평가)
A가 falsy면 B를 평가해서 그 값을 반환
true || "Hello" // true (첫 번째가 truthy라 두 번째 안 봄)
false || "Hello" // "Hello" (첫 번째 falsy라 두 번째 반환)
0 || 42 // 42 (0 falsy)
"Hi" || 123 // "Hi" (첫 번째 truthy라 반환)
"" || "default" // "default" (빈 문자열 falsy)
const input = null;
const name = input || "Guest";
console.log(name); // "Guest"
numMap.set(num, (numMap.get(num) || 0) + 1);
빈도수 세기
const arr = [1, 1, 2, 3, 2, 4];
const map = new Map();
for (const num of arr) {
map.set(num, (map.get(num) || 0) + 1);
}
console.log(map); // Map { 1 => 2, 2 => 2, 3 => 1, 4 => 1 }
아래의 값이 flasy 값이며 그 외는 전부 truthy 값이다.
false
0
"" (빈 문자열)
null
undefined
NaN
배열의 모든 요소에 대해 콜백 함수를 실행하지만 새로운 배열을 반환하지는 않음
리턴값 없음!!
단순히 배열을 순회하며 작업할때 좋다!
중간에 break나 return 불가능
array.forEach((element, index, array) => {
// 작업 수행
});
const arr = [1, 2, 3];
arr.forEach(num => {
console.log(num * 2); // 2, 4, 6
});
const arr = [5, 10, 15, 20];
arr.forEach((item, index) => {
if (item > 12) {
console.log(`조건 만족: 값 = ${item}, 인덱스 = ${index}`);
}
});
value, key, map 이다!)map.forEach((value, key, map) => { ... });
const map = new Map();
const origalFileArr = getOriginalFileArr(param0);
// 카운트
origalFileArr.forEach(e => {
map.set(e, (map.get(e) || 0) + 1);
});
// 삭제할 키 배열로 모아둠
const keysToDelete = [];
map.forEach((value, key) => {
if (value === 1) {
keysToDelete.push(key);
}
});
// 삭제 수행
keysToDelete.forEach(key => map.delete(key));
return map;
배열에서 특정 조건을 만족하는 요소들만 추출하여 새로운 배열을 반환
조건이 true인 요소만 새로운 배열에 포함
원본 배열은 변경하지 않음
중간에 break 불가능
const newArray = array.filter((element, index, array) => {
return 조건; // true인 요소만 남김
});
const arr = [1, 2, 3, 4, 5];
const even = arr.filter(num => num % 2 === 0);
console.log(even); // [2, 4]
let arrMap = new Map([
[a, [Math.abs(card - aLast), aLast]],
[b, [Math.abs(card - bLast), bLast]],
[c, [Math.abs(card - cLast), cLast]],
[d, [Math.abs(card - dLast), dLast]]
]);
let sorted = [...arrMap.entries()]
.filter(([key, _]) => key.length > 0) // 빈 배열 제외
.sort((a, b) => a[1][0] - b[1][0]); // 절대값 차이 기준 정렬
let sortedArrMap = new Map(sorted);
let valuesArr = [...sortedArrMap.values()];
Map.entries()는 [key, value] 쌍으로 이루어진 배열을 반환하므로
.filter(([key, _]) => ...)처럼 구조분해할당을 통해 key만 뽑아서 사용할 수 있음.
‼️주의‼️ 구조분해 한 것은 새로운 변수에 할당한 것이기 때문에 구조분해 한 변수를 아무리 수정해도 원본은 수정되지 않는다!!!
const arrMap = new Map([
[[1, 2], [10, 20]],
[[], [30, 40]]
]);
let sorted = [...arrMap.entries()]
.filter((key) => key.length > 0) // 여기가 틀림
.sort((a, b) => a[1][0] - b[1][0]);
Map.entries()에서 나오는 요소는[key, value] 배열이다.[ [ [1, 2], [10, 20] ], [ [], [30, 40] ] ]즉, 각 항목은 길이가 2인 배열이다.
- [key, value]의 형태이고
- 예: [ [1, 2], [10, 20] ] → 이 전체가 하나의 entry
그런데 여기서 key라는 이름으로 받으면 실제는 [key, value] 한 쌍 전체를 통째로 key라는 이름으로 받게 된다.
그래서 key.length는 항상 2(key, value 두 개)(배열 길이) 이고, key.length > 0은 항상 참이 된다.
즉, 빈 배열 필터링은 전혀 안 되고, 전부 통과시키게 됨.
없으면 undefined를 반환
arr.find((element, index, array) => 조건);
const numbers = [3, 7, 11, 20];
const result = numbers.find((num) => num > 10);
console.log(result); // 11
없으면 -1을 반환
arr.findIndex((element, index, array) => 조건);
const numbers = [3, 7, 11, 20];
const index = numbers.findIndex((num) => num > 10);
console.log(index); // 2
str.repeat(count)
console.log("abc".repeat(3)); // "abcabcabc"
console.log("*".repeat(5)); // "*****"
count가 음수이거나 무한대면 RangeError 발생
원본은 변경하지 않음
str.slice(start, end)
arr.slice(start, end)
const str = "Hello, world!";
console.log(str.slice(0, 5)); // "Hello"
console.log(str.slice(7)); // "world!"
console.log(str.slice(-6)); // "world!"
const arr = [1, 2, 3, 4, 5];
const newArr = arr.slice(1, 4); // 인덱스 1부터 3까지
console.log(newArr); // [2, 3, 4]
console.log(arr); // [1, 2, 3, 4, 5] ← 원본 유지
arr.splice(start, deleteCount, item1, item2, ...)
1️⃣ 인자로 전달된 값들을 먼저 모두 평가(계산)
2️⃣ 배열에서 요소 삭제 (deleteCount)
3️⃣ 지운 자리에 평가된 값들을 삽입
const arr = [0, 100];
const divisor = 2;
arr.splice(1, 1, arr[1] / divisor); // 100 / 2 = 50
console.log(arr); // [0, 50]
삭제된 요소들로 구성된 배열을 반환
splice(위치, 개수)
const arr = [1, 2, 3, 4, 5];
const removed = arr.splice(1, 2); // 인덱스 1부터 2개 제거
console.log(removed); // [2, 3]
console.log(arr); // [1, 4, 5] ← 원본 변경됨
splice(위치, 0, 값)
arr.splice(1, 0, 99); // 인덱스 1에 아무것도 삭제하지 않고 99 삽입
console.log(arr); // [1, 99, 4, 5]
const arr = [1, 2, 5, 6];
arr.splice(2, 0, 3, 4); // 인덱스 2에 아무것도 삭제하지 않고, 3과 4를 삽입
console.log(arr); // [1, 2, 3, 4, 5, 6]
splice(위치, 개수, 새값...)
const arr = ['a', 'b', 'c', 'd'];
// 인덱스 1부터 2개 삭제하고 'x', 'y'로 교체
arr.splice(1, 2, 'x', 'y');
console.log(arr); // ['a', 'x', 'y', 'd']
const arr = [1, 2, 3, 4];
arr.splice(-2, 1); // 끝에서 두 번째(3) 제거
console.log(arr); // [1, 2, 4]
NaN은 타입이 number console.log(typeof NaN); // "number"
연산에 실패하거나 숫자가 아닌 걸 숫자로 바꾸려 할 때 생긴다
console.log(Number("abc")); // NaN
console.log(0 / 0); // NaN
console.log(Math.sqrt(-1)); // NaN
console.log("hello" * 3); // NaN
진짜 NaN값만 true로 판단
Number.isNaN('a'); // false
'a'는 문자열이고, Number.isNaN()은 "진짜 NaN 값"만 true로 판단함
'a'는 NaN이 아니고, 그냥 문자열이라서 false
console.log(NaN === NaN); // false
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(Number('abc'))); // true // 'a' -> Number('a') -> NaN
‼️ 비교할 땐 반드시 Number.isNaN() 사용 ‼️
내용이 많아서 따로 포스트로 정리함
https://velog.io/@seha01130/Javascript-Map-정리-qgd9dzxd
let str = 'abc';
str[0] = 'X'; // 아무 효과 없음
console.log(str); // 'abc'
let newStr = '';
newStr += 'X'; // 'X'
newStr += 'b'; // 'Xb'
newStr += 'c'; // 'Xbc'
console.log(newStr); // 'Xbc'
.lengthcharCodeAt, 그걸 다시 문자로 되돌리는 String.fromCharCode()let ch = 'A';
let code = ch.charCodeAt(0); // 65
let back = String.fromCharCode(code); // 'A'
console.log(code); // 65
console.log(back); // 'A'
let arr = ['a', 'b', 'c'];
let last = arr.pop();
console.log(last); // "c"
console.log(arr); // ["a", "b"]
경로에서 파일명만 추출
const path = "/a/b/c/file.txt";
const fileName = path.split('/').pop(); // "file.txt"