개발

[모던 자바스크립트 DeepDive] Js 심화 스터디 week 6

sjindev 2025. 8. 10. 17:45

ES6 함수의 추가기능

함수의 구분

ES6 이후 자바스크립트의 함수는 의도와 동작 방식에 따라 명확하게 구분됨.

1.1 함수의 종류

일반 함수 (Normal Function)

  • function 키워드를 사용해 선언
  • 생성자 함수로 사용 가능 (new 가능)
  • 호출 방식에 따라 this 바인딩이 달라짐

메서드 (Method)

  • 객체의 프로퍼티 값이 함수인 경우
  • super 키워드 사용 가능
  • 생성자 함수로 사용 불가 (new 불가)

화살표 함수 (Arrow Function)

생성자 함수 (Constructor Function)

  • new 연산자와 함께 호출되어 인스턴스를 생성
  • 클래스 문법의 기반
function normalFunc() {
  console.log("일반 함수");
}

const obj = {
  method() {
    console.log("메서드");
  }
};

const arrow = () => console.log("화살표 함수");

new normalFunc(); // OK
// new obj.method(); // TypeError
// new arrow(); // TypeError

메서드

예시 코드

const person = {
  name: "KSJ",
  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.sayHello(); // Hello, my name is KSJ

특징

  • 메서드는 프로토타입의 메서드로 정의됨
  • super 키워드를 사용해 부모 객체 메서드 호출 가능
  • 생성자 함수처럼 new로 호출 불가.
const parent = {
  greet() {
    return "Hello";
  }
};

const child = {
  greet() {
    return `${super.greet()} World`;
  }
};

Object.setPrototypeOf(child, parent);
console.log(child.greet()); // Hello World

화살표 함수

예시코드

const add = (a, b) => a + b;
console.log(add(2, 3)); // 5

특징

  • this, arguments, super, new.target을 바인딩하지 않음.
  • 항상 상위 스코프의 this를 참조 (렉시컬 this).
  • 메서드로 사용하면 안 됨 (객체 메서드 내부의 this 참조 불가).
const obj = {
  value: 42,
  arrow: () => console.log(this.value),
  normal: function () {
    console.log(this.value);
  }
};

obj.arrow(); // undefined (전역 this 참조)
obj.normal(); // 42

화살표함수 vs 일반함수

구분 일반 함수 화살표 함수
this 호출 방식에 따라 동적 바인딩 상위 스코프의 this(렉시컬 바인딩)
arguments 전달된 인수 유사배열로 접근 가능 없음(상위 스코프의 arguments 참조)
생성자 사용 가능 불가능
super 사용 가능 없음
코드 길이 길어질 수 있음 간결

Rest 파라미터

ES6에서 추가된 문법으로, 가변 인자를 배열로 한 번에 받을 수 있는 기능

function sum(...numbers) {
  return numbers.reduce((acc, cur) => acc + cur, 0);
}

console.log(sum(1, 2, 3, 4)); // 10

특징

  • 항상 마지막 매개변수에만 사용 가능
  • 함수의 length 프로퍼티에 영향을 주지 않음.
  • arguments 객체보다 직관적
function log(a, b, ...rest) {
  console.log(a);    // 첫 번째 인자
  console.log(b);    // 두 번째 인자
  console.log(rest); // 나머지 인자 배열
}

log(1, 2, 3, 4, 5);

매개변수 기본값

ES6부터 매개변수에 기본값을 직접 설정할 수 있음.

function greet(name = "Guest") {
  console.log(`Hello, ${name}`);
}

greet(); // Hello, Guest
greet("KSJ"); // Hello, KSJ
  • 함수 호출 시 인자를 생략하거나 undefined를 전달하면 기본값 사용.
  • 기본값 표현식에서 다른 매개변수를 참조 가능.

배열

1. 자바스크립트 배열은 배열이 아니다

자바스크립트의 배열은자료구조에서 말하는 일반적인 배열(Array)과 다름.

  • 전통적인 배열(C, Java): 메모리상에 같은 타입의 데이터가 연속적으로 저장됨.
  • 자바스크립트 배열: 해시 테이블 기반의 객체(Object)로, 인덱스를 키로 사용하는 특수한 객체입니다.

즉, JS 배열은 동일한 타입과 연속적인 메모리 구조를 강제하지 않으며, 다양한 타입의 데이터를 섞어 저장할 수 있다.

const arr = [1, 'text', true, { key: 'value' }];
console.log(typeof arr); // 'object'

2. length 프로퍼티와 희소 배열

2.1 length 프로퍼티

  • 배열의 length는 요소 개수가 아니라 가장 큰 인덱스 + 1 값.
  • 요소를 삭제하거나 인덱스를 건너뛰면 실제 요소 개수보다 length가 더 클 수 있다.
const arr = [];
arr[3] = 'hello';
console.log(arr.length); // 4 (0~3 인덱스)

2.2 희소 배열(Sparse Array)

  • 중간 인덱스에 값이 없는 배열을 희소 배열이라고 함.
  • 빈 요소는 undefined가 아니라 존재하지 않는 값으로 취급.
const sparse = [1, , 3];
console.log(sparse.length); // 3
console.log(sparse[1]); // undefined (요소가 없음)
console.log(1 in sparse); // false

3. 배열 생성(간단한 코드로 문법 확인)

3.1 배열 리터럴

const arr = [1, 2, 3];

3.2 Array 생성자

const arr1 = new Array(3); // 길이 3, 빈 요소
const arr2 = new Array(1, 2, 3); // 요소 1,2,3

3.3 Array.of()

const arr = Array.of(3); // [3]

3.4 Array.from()

const arr = Array.from('abc'); // ['a', 'b', 'c']

4. 배열 요소의 참조

  • 인덱스는 0부터 시작.
  • 존재하지 않는 인덱스 접근 시 undefined 반환.
const arr = ['a', 'b'];
console.log(arr[0]); // 'a'
console.log(arr[5]); // undefined

5. 배열 요소의 추가와 갱신

const arr = [1, 2];
arr[2] = 3; // 추가
arr[1] = 20; // 갱신
  • 인덱스를 건너뛰어 추가하면 희소 배열 생성.

6. 배열 요소의 삭제

6.1 delete 연산자

const arr = [1, 2, 3];
delete arr[1];
console.log(arr); // [1, <empty>, 3]
  • 요소는 삭제되지만, length는 변하지 않고 빈 슬롯 유지.

6.2 splice() 사용 (권장)

const arr = [1, 2, 3];
arr.splice(1, 1);
console.log(arr); // [1, 3]

7. 배열 메서드

7.1 변경 메서드 (원본을 수정)

  • push(), pop()
  • shift(), unshift()
  • splice()
  • sort(), reverse()

7.2 비변경 메서드 (새 배열을 반환)

  • concat()
  • slice()
  • map(), filter()
  • reduce(), reduceRight()

8. 얕은 복사 vs 깊은 복사

8.1 얕은 복사

  • 참조형 데이터의 참조 값만 복사.
const arr1 = [1, 2, 3];
const arr2 = arr1;
arr2[0] = 99;
console.log(arr1[0]); // 99

8.2 깊은 복사

  • 실제 값까지 완전히 복사.
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
arr2[0] = 99;
console.log(arr1[0]); // 1
  • 중첩 객체일 경우 structuredClone() 또는 lodash.cloneDeep() 권장.

9. 배열 고차 함수

고차 함수(Higher-Order Function)는 함수를 인수로 받거나 함수를 반환하는 함수.

  • forEach() : 단순 반복
  • map() : 요소 변환
  • filter() : 조건 필터링
  • reduce() : 누적 계산
  • find(), findIndex() : 조건 검색
const nums = [1, 2, 3, 4];
const doubled = nums.map(n => n * 2); // [2, 4, 6, 8]

10. JSON.stringify 메서드

배열이나 객체를 JSON 문자열로 변환.

const arr = [1, 2, 3];
const json = JSON.stringify(arr);
console.log(json); // "[1,2,3]"
  • 함수나 undefined는 무시됨.
const arr = [1, undefined, function(){}];
console.log(JSON.stringify(arr)); // [1,null,null]

요약정리

  • JS 배열은 객체이지만, 인덱스 기반 데이터 관리에 최적화된 구조.
  • length와 희소 배열 개념을 이해하면 예기치 못한 버그 방지 가능.
  • 원본 변경 여부에 따라 메서드를 구분해 사용.
  • 얕은 복사/깊은 복사 차이를 이해해야 참조 문제를 피할 수 있음.
  • JSON 직렬화 시 undefined와 함수는 제외됨.

Number, Math, Date

Number

Number 생성자 함수

  • 숫자 값을 생성하기 위한 래퍼 객체 생성자 함수
  • new 연산자와 함께 호출 시 Number 객체 생성
  • new 없이 호출 시 숫자 타입 변환 수행
  • 예시
new Number(10); // Number 객체
Number('123'); // 숫자 123

Number 프로퍼티

  • Number.EPSILON : 1과 1보다 큰 수 중에서 가장 작은 수의 차이값
  • Number.MAX_VALUE : 자바스크립트에서 표현 가능한 가장 큰 수
  • Number.MIN_VALUE : 자바스크립트에서 표현 가능한 가장 작은 수(0에 가장 가까운 양수)
  • Number.MAX_SAFE_INTEGER : 안전하게 표현할 수 있는 최대 정수값 (2^53 - 1)
  • Number.MIN_SAFE_INTEGER : 안전하게 표현할 수 있는 최소 정수값 (-(2^53 - 1))
  • Number.POSITIVE_INFINITY : 양의 무한대
  • Number.NEGATIVE_INFINITY : 음의 무한대
  • Number.NaN : Not-a-Number 값

Number 메서드

  • Number.isFinite() : 유한수 여부 판별
  • Number.isInteger() : 정수 여부 판별
  • Number.isNaN() : NaN 여부 판별
  • Number.isSafeInteger() : 안전한 정수 여부 판별
  • Number.parseFloat() : 문자열을 부동소수점 숫자로 변환
  • Number.parseInt() : 문자열을 정수로 변환
  • toExponential() : 지수 표기법 문자열로 변환
  • toFixed() : 고정 소수점 표기 문자열로 변환
  • toPrecision() : 지정된 자릿수의 문자열로 변환

Math

Math 프로퍼티

  • Math.PI : 원주율(π) 값
  • Math.E : 자연로그의 밑(e)
  • Math.LN2 : 2의 자연로그
  • Math.LN10 : 10의 자연로그
  • Math.LOG2E : e의 밑이 2인 로그값
  • Math.LOG10E : e의 밑이 10인 로그값

Math 메서드

  • Math.abs() : 절대값 반환
  • Math.ceil() : 올림
  • Math.floor() : 내림
  • Math.round() : 반올림
  • Math.trunc() : 소수점 이하 버림
  • Math.max() : 최대값 반환
  • Math.min() : 최소값 반환
  • Math.pow() : 거듭제곱 계산
  • Math.sqrt() : 제곱근 계산
  • Math.random() : 0 이상 1 미만 난수 생성
  • Math.sign() : 부호 반환 (양수 1, 음수 -1, 0)

Date

Date 생성자 함수

  • 날짜와 시간을 표현하는 객체 생성
  • new Date() : 현재 날짜와 시간 반환
  • new Date(milliseconds) : 1970-01-01 00:00:00 UTC부터 지정된 밀리초 경과 시점
  • new Date(dateString) : 날짜 문자열 기반 객체 생성
  • new Date(year, month[, day, hour, minute, second, millisecond]) : 지정된 날짜/시간 기반 생성

Date 메서드

  • Getter 메서드
    • getFullYear() : 연도 반환
    • getMonth() : 월(0~11) 반환
    • getDate() : 일(1~31) 반환
    • getDay() : 요일(0~6) 반환 (일요일=0)
    • getHours() : 시 반환
    • getMinutes() : 분 반환
    • getSeconds() : 초 반환
    • getMilliseconds() : 밀리초 반환
    • getTime() : 1970-01-01 00:00:00 UTC부터 경과한 밀리초
    • getTimezoneOffset() : 로컬과 UTC 차이(분)
  • Setter 메서드
    • setFullYear() : 연도 설정
    • setMonth() : 월 설정
    • setDate() : 일 설정
    • setHours() : 시 설정
    • setMinutes() : 분 설정
    • setSeconds() : 초 설정
    • setMilliseconds() : 밀리초 설정
    • setTime() : 밀리초 기반 날짜 설정
  • 기타 메서드
    • toDateString() : 사람이 읽기 쉬운 날짜 문자열 반환
    • toTimeString() : 사람이 읽기 쉬운 시간 문자열 반환
    • toISOString() : ISO 8601 형식 문자열 반환
    • toLocaleDateString() : 지역화된 날짜 문자열 반환
    • toLocaleTimeString() : 지역화된 시간 문자열 반환

    RegExp

1. 정규표현식이란?

  • 문자열에서 특정 패턴을 검색, 추출, 치환하기 위해 사용하는 표현식
  • 문자열 처리에서 강력한 패턴 매칭 기능 제공
  • 주로 데이터 유효성 검사, 문자열 검색, 문자열 변환 등에 사용
  • JavaScript에서는 RegExp 객체로 표현

2. 정규표현식의 생성

리터럴 표기법

const regex = /pattern/flags;
  • /로 시작하고 종료
  • pattern은 검색할 패턴
  • flags는 검색 방식 지정
  • 코드 실행 시점에 정규표현식이 고정됨

생성자 함수 표기법

const regex = new RegExp('pattern', 'flags');
  • 문자열로 패턴과 플래그를 전달
  • 런타임에 동적으로 정규표현식 생성 가능

3. RegExp 메서드

3.1 RegExp.prototype.exec()

  • 정규표현식과 매치되는 문자열 반환
  • 일치하면 배열, 불일치 시 null 반환
const regex = /abc/;
console.log(regex.exec('abcdef')); // ["abc"]

3.2 RegExp.prototype.test()

  • 일치 여부를 불리언 값으로 반환
const regex = /abc/;
console.log(regex.test('abcdef')); // true

3.3 String.prototype.match()

  • 문자열에서 정규표현식과 일치하는 부분을 배열로 반환
const str = 'hello world';
console.log(str.match(/world/)); // ["world"]

3.4 String.prototype.replace()

  • 정규표현식에 매칭되는 부분을 치환
const str = 'hello world';
console.log(str.replace(/world/, 'JavaScript')); // hello JavaScript

3.5 String.prototype.search()

  • 일치하는 첫 번째 인덱스 반환, 없으면 -1 반환
const str = 'hello world';
console.log(str.search(/world/)); // 6

3.6 String.prototype.split()

  • 정규표현식을 구분자로 사용하여 문자열 분리
const str = 'apple,banana,orange';
console.log(str.split(/,/)); // ["apple", "banana", "orange"]

4. 플래그

  • g : 전역 검색 (모든 일치 항목 검색)
  • i : 대소문자 구분 없이 검색
  • m : 다중 행 모드 (각 행의 시작과 끝을 인식)
  • u : 유니코드 모드
  • y : "sticky" 모드, lastIndex부터만 검색
const regex = /abc/gi; // 대소문자 무시, 전역 검색

5. 패턴

5.1 메타문자

  • . : 임의의 한 문자
  • ^ : 문자열 시작
  • $ : 문자열 끝
  • [] : 문자 집합
  • [^] : 부정 문자 집합
  • | : OR 연산자
  • () : 그룹화

5.2 수량자

  • * : 0회 이상 반복
  • + : 1회 이상 반복
  • ? : 0 또는 1회
  • {n} : n회 반복
  • {n,} : n회 이상 반복
  • {n,m} : n회 이상 m회 이하 반복

5.3 이스케이프 문자

  • \ : 메타문자를 일반 문자로 인식
  • 예: \.. 문자 자체

5.4 자주 쓰는 패턴

  • \d : 숫자
  • \D : 숫자가 아닌 문자
  • \w : 알파벳, 숫자, 밑줄
  • \W : 위 문자가 아닌 것
  • \s : 공백 문자
  • \S : 공백이 아닌 문자

String 객체 정리

String 생성자 함수

  • String 생성자 함수는 문자열을 생성하는 함수 객체임
  • new String(value) 형태로 호출 시 String 래퍼 객체 생성됨
  • 인자를 전달하지 않으면 빈 문자열 생성됨
  • 문자열 리터럴("hello")과 달리, 생성자 함수로 만든 값은 객체로 취급됨
  • typeof 연산 시 객체(object)로 반환됨
  • 문자열 원시값과 달리 프로토타입 메서드 호출 시 내부적으로 객체로 변환되는 과정 존재함
const str1 = 'hello';
const str2 = new String('hello');
console.log(typeof str1); // string
console.log(typeof str2); // object

length 프로퍼티

  • 문자열의 길이를 나타내는 읽기 전용 프로퍼티임
  • 공백, 특수문자 포함하여 길이 계산됨
  • str.length 형태로 접근함
  • 변경 불가, 재할당 불가
const str = 'hello world';
console.log(str.length); // 11

String 메서드

1. 문자 접근

  • charAt(index) : 지정 인덱스 위치 문자 반환
  • charCodeAt(index) : 지정 인덱스 문자의 UTF-16 코드 반환
  • 대괄호 표기(str[index])로 접근 가능

2. 문자열 검색

  • indexOf(searchValue, fromIndex) : 왼쪽에서 검색하여 첫 번째 인덱스 반환
  • lastIndexOf(searchValue, fromIndex) : 오른쪽에서 검색하여 첫 번째 인덱스 반환
  • includes(searchString, position) : 포함 여부 불리언 반환
  • startsWith(searchString, position) : 시작 여부 확인
  • endsWith(searchString, length) : 끝 여부 확인

3. 문자열 변환

  • toUpperCase() : 대문자 변환
  • toLowerCase() : 소문자 변환
  • trim() : 양쪽 공백 제거
  • trimStart() / trimEnd() : 시작/끝 공백 제거

4. 문자열 추출

  • slice(start, end) : start~end 미만 잘라내기
  • substring(start, end) : 인덱스 기반 부분 문자열 추출
  • substr(start, length) : 시작 인덱스와 길이 기반 추출 (Deprecated)

5. 문자열 치환

  • replace(searchValue, replaceValue) : 첫 번째 일치 부분 치환
  • replaceAll(searchValue, replaceValue) : 모든 일치 부분 치환

6. 문자열 분리/결합

  • split(separator, limit) : 구분자로 분할하여 배열 반환
  • concat(...strings) : 문자열 결합

7. 기타 메서드

  • repeat(count) : 지정 횟수만큼 반복한 문자열 생성
  • padStart(targetLength, padString) : 앞쪽 채우기
  • padEnd(targetLength, padString) : 뒤쪽 채우기