JavaScript/기초 문법과 자료형

JavaScript 자료형 완전 가이드 - 문자열, 숫자, 불린, 배열, 객체 마스터하기

코딩하는 패션이과생 2025. 5. 16. 01:32
반응형

자료형이란?

자료형(Data Type)은 프로그래밍에서 데이터의 종류를 정의하는 개념입니다. JavaScript는 동적 타이핑 언어로, 변수의 자료형을 선언할 때 지정하지 않고 런타임에 결정됩니다.

🔍 JavaScript 자료형 분류

JavaScript의 자료형은 크게 두 가지로 나뉩니다:

  1. 원시 자료형 (Primitive Types)
    • String, Number, Boolean, undefined, null, Symbol, BigInt
  2. 참조 자료형 (Reference Types)
    • Object, Array, Function

원시 자료형 개요

📝 원시 자료형의 특징

// 원시 자료형은 값 자체를 저장
let a = 10;
let b = a;
a = 20;

console.log(a); // 20
console.log(b); // 10 (a의 변경이 b에 영향 없음)

🔄 불변성 (Immutability)

// 문자열은 불변
let str = "Hello";
str[0] = "h"; // 변경되지 않음
console.log(str); // "Hello"

// 새로운 값을 할당해야 변경
str = "hello";
console.log(str); // "hello"

문자열 (String)

📖 문자열 기본

문자열은 텍스트 데이터를 저장하는 자료형입니다.

// 문자열 생성 방법
let singleQuote = '안녕하세요';
let doubleQuote = "Hello World";
let templateLiteral = `템플릿 리터럴`;

console.log(singleQuote);    // "안녕하세요"
console.log(doubleQuote);    // "Hello World"
console.log(templateLiteral); // "템플릿 리터럴"

🔤 템플릿 리터럴 (Template Literals)

// 백틱(`)을 사용한 템플릿 리터럴
let name = "김철수";
let age = 25;

// 변수 삽입
let introduce = `안녕하세요, 저는 ${name}이고 ${age}살입니다.`;
console.log(introduce); // "안녕하세요, 저는 김철수이고 25살입니다."

// 표현식 사용
let calculation = `2 + 3 = ${2 + 3}`;
console.log(calculation); // "2 + 3 = 5"

// 여러 줄 문자열
let multiLine = `
첫 번째 줄
두 번째 줄
세 번째 줄
`;
console.log(multiLine);

🛠️ 문자열 메서드

let text = "JavaScript Programming";

// 길이 확인
console.log(text.length); // 22

// 대소문자 변환
console.log(text.toLowerCase()); // "javascript programming"
console.log(text.toUpperCase()); // "JAVASCRIPT PROGRAMMING"

// 문자열 검색
console.log(text.indexOf("Script")); // 4
console.log(text.includes("Java"));  // true

// 문자열 분할
console.log(text.split(" ")); // ["JavaScript", "Programming"]

// 문자열 자르기
console.log(text.slice(0, 10));    // "JavaScript"
console.log(text.substring(0, 10)); // "JavaScript"

// 문자열 대체
console.log(text.replace("JavaScript", "JS")); // "JS Programming"

// 공백 제거
let spacyText = "  Hello World  ";
console.log(spacyText.trim()); // "Hello World"

💡 문자열 실습 예제

// 이메일 유효성 검사
function validateEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
}

console.log(validateEmail("user@example.com")); // true
console.log(validateEmail("invalid-email"));    // false

// 문자열 포매팅
function formatKoreanName(lastName, firstName) {
    return `${lastName}${firstName}`;
}

function formatPhoneNumber(number) {
    // 010-1234-5678 형태로 포매팅
    return number.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3');
}

console.log(formatKoreanName("김", "철수")); // "김철수"
console.log(formatPhoneNumber("01012345678")); // "010-1234-5678"

숫자 (Number)

🔢 숫자 자료형 기본

JavaScript는 정수와 실수를 구분하지 않고 모두 Number 타입으로 처리합니다.

// 다양한 숫자 표현
let integer = 42;
let float = 3.14159;
let negative = -100;
let scientific = 1.5e10; // 1.5 * 10^10

console.log(integer);    // 42
console.log(float);      // 3.14159
console.log(negative);   // -100
console.log(scientific); // 15000000000

🧮 숫자 연산

// 기본 연산
let a = 10;
let b = 3;

console.log(a + b);  // 13 (덧셈)
console.log(a - b);  // 7  (뺄셈)
console.log(a * b);  // 30 (곱셈)
console.log(a / b);  // 3.3333... (나눗셈)
console.log(a % b);  // 1  (나머지)
console.log(a ** b); // 1000 (거듭제곱)

// 증감 연산
let count = 5;
console.log(++count); // 6 (전위 증가)
console.log(count++); // 6 (후위 증가, 출력 후 증가)
console.log(count);   // 7

🔍 특수한 숫자 값

// Infinity와 -Infinity
console.log(1 / 0);    // Infinity
console.log(-1 / 0);   // -Infinity
console.log(Infinity + 1); // Infinity

// NaN (Not a Number)
console.log(0 / 0);       // NaN
console.log("문자" * 2);   // NaN
console.log(Math.sqrt(-1)); // NaN

// NaN 검사
console.log(isNaN(NaN));     // true
console.log(Number.isNaN(NaN)); // true (더 정확한 방법)

🛠️ Number 메서드

let num = 123.456789;

// 문자열로 변환
console.log(num.toString());     // "123.456789"
console.log(num.toString(2));    // "1111011.0111..." (2진수)

// 소수점 제어
console.log(num.toFixed(2));     // "123.46"
console.log(num.toPrecision(5)); // "123.46"

// Math 객체 활용
console.log(Math.round(num));    // 123 (반올림)
console.log(Math.floor(num));    // 123 (내림)
console.log(Math.ceil(num));     // 124 (올림)
console.log(Math.abs(-num));     // 123.456789 (절댓값)
console.log(Math.max(1, 5, 3));  // 5
console.log(Math.min(1, 5, 3));  // 1
console.log(Math.random());      // 0~1 사이의 랜덤 수

💰 숫자 실습 예제

// 금액 포매팅
function formatCurrency(amount) {
    return new Intl.NumberFormat('ko-KR', {
        style: 'currency',
        currency: 'KRW'
    }).format(amount);
}

console.log(formatCurrency(1234567)); // "₩1,234,567"

// 퍼센트 계산
function calculatePercentage(value, total) {
    return Math.round((value / total) * 100 * 100) / 100; // 소수점 2자리
}

console.log(calculatePercentage(75, 100)); // 75
console.log(calculatePercentage(33, 99));  // 33.33

// 랜덤 정수 생성
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

console.log(getRandomInt(1, 100)); // 1~100 사이의 랜덤 정수

불린 (Boolean)

✅ 불린 자료형 기본

불린은 참(true) 또는 거짓(false) 값을 저장하는 자료형입니다.

// 불린 값
let isTrue = true;
let isFalse = false;

console.log(isTrue);  // true
console.log(isFalse); // false
console.log(typeof isTrue); // "boolean"

🔄 불린 변환

// Truthy 값들 (참으로 평가되는 값)
console.log(Boolean(1));        // true
console.log(Boolean("Hello"));  // true
console.log(Boolean([]));       // true
console.log(Boolean({}));       // true
console.log(Boolean(-1));       // true

// Falsy 값들 (거짓으로 평가되는 값)
console.log(Boolean(0));        // false
console.log(Boolean(""));       // false
console.log(Boolean(null));     // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN));      // false
console.log(Boolean(false));    // false

🔗 논리 연산자

// AND (&&) 연산자
console.log(true && true);   // true
console.log(true && false);  // false
console.log(false && true);  // false

// OR (||) 연산자
console.log(true || false);  // true
console.log(false || false); // false

// NOT (!) 연산자
console.log(!true);   // false
console.log(!false);  // true
console.log(!!true);  // true (이중 부정)

// 단축 평가 (Short-circuit evaluation)
let user = null;
let defaultName = "게스트";
let displayName = user || defaultName;
console.log(displayName); // "게스트"

// Nullish coalescing (??)
let value = null;
let defaultValue = "기본값";
let result = value ?? defaultValue;
console.log(result); // "기본값"

🎯 불린 실습 예제

// 사용자 권한 체크
function hasPermission(user, resource) {
    return user.isActive && 
           user.role === 'admin' && 
           user.permissions.includes(resource);
}

const user = {
    isActive: true,
    role: 'admin',
    permissions: ['read', 'write', 'delete']
};

console.log(hasPermission(user, 'write')); // true

// 조건부 메시지 표시
function getStatusMessage(isLoggedIn, hasUnreadMessages) {
    if (isLoggedIn && hasUnreadMessages) {
        return "새 메시지가 있습니다.";
    } else if (isLoggedIn && !hasUnreadMessages) {
        return "안녕하세요!";
    } else {
        return "로그인이 필요합니다.";
    }
}

console.log(getStatusMessage(true, true));   // "새 메시지가 있습니다."
console.log(getStatusMessage(true, false));  // "안녕하세요!"
console.log(getStatusMessage(false, true));  // "로그인이 필요합니다."

undefined와 null

🤔 undefined vs null

// undefined: 선언되었지만 값이 할당되지 않음
let declaredButNotAssigned;
console.log(declaredButNotAssigned); // undefined
console.log(typeof declaredButNotAssigned); // "undefined"

// null: 명시적으로 "값이 없음"을 나타냄
let explicitlyEmpty = null;
console.log(explicitlyEmpty); // null
console.log(typeof explicitlyEmpty); // "object" (JavaScript의 오래된 버그)

🔍 undefined가 나타나는 경우

// 1. 선언만 하고 초기화하지 않은 변수
let uninitialized;
console.log(uninitialized); // undefined

// 2. 객체에 존재하지 않는 속성
let obj = { name: "김철수" };
console.log(obj.age); // undefined

// 3. 배열의 범위를 벗어난 인덱스
let arr = [1, 2, 3];
console.log(arr[10]); // undefined

// 4. 함수에서 return문이 없거나 return만 사용
function noReturn() {
    // return 없음
}
console.log(noReturn()); // undefined

function emptyReturn() {
    return; // 값 없이 return
}
console.log(emptyReturn()); // undefined

// 5. 함수의 매개변수에 값이 전달되지 않음
function greet(name) {
    console.log(`안녕하세요, ${name}님`);
}
greet(); // "안녕하세요, undefined님"

🛡️ null과 undefined 체크

// null/undefined 구분하기
function checkValue(value) {
    if (value === null) {
        return "null입니다";
    } else if (value === undefined) {
        return "undefined입니다";
    } else {
        return "값이 있습니다";
    }
}

console.log(checkValue(null));      // "null입니다"
console.log(checkValue(undefined)); // "undefined입니다"
console.log(checkValue("값"));       // "값이 있습니다"

// null 또는 undefined 체크 (Nullish 체크)
function safeAccess(obj, property, defaultValue = "기본값") {
    return obj?.[property] ?? defaultValue;
}

const user = { name: "김철수" };
console.log(safeAccess(user, "name"));  // "김철수"
console.log(safeAccess(user, "age"));   // "기본값"
console.log(safeAccess(null, "name"));  // "기본값"

Symbol과 BigInt

🔮 Symbol (ES6)

Symbol은 유일한 식별자를 만들 때 사용하는 원시 자료형입니다.

// Symbol 생성
let symbol1 = Symbol();
let symbol2 = Symbol();
let symbol3 = Symbol("description");

console.log(symbol1 === symbol2); // false (각각 유일함)
console.log(symbol3.toString());  // "Symbol(description)"

// 객체 속성으로 사용
const SECRET_KEY = Symbol("secret");
let obj = {
    [SECRET_KEY]: "비밀 값",
    normalKey: "일반 값"
};

console.log(obj[SECRET_KEY]); // "비밀 값"
console.log(Object.keys(obj)); // ["normalKey"] (Symbol 속성은 숨겨짐)

🔢 BigInt (ES2020)

BigInt는 Number.MAX_SAFE_INTEGER보다 큰 정수를 다룰 때 사용합니다.

// BigInt 생성
let bigNumber1 = 123456789012345678901234567890n;
let bigNumber2 = BigInt("123456789012345678901234567890");

console.log(bigNumber1); // 123456789012345678901234567890n
console.log(typeof bigNumber1); // "bigint"

// BigInt 연산 (같은 타입끼리만 가능)
let big1 = 10n;
let big2 = 20n;
console.log(big1 + big2); // 30n

// Number와 BigInt 혼용 불가
// console.log(10n + 10); // TypeError
console.log(10n + BigInt(10)); // 20n
console.log(Number(10n) + 10); // 20

참조 자료형: 객체

🏗️ 객체 기본

객체는 키-값 쌍으로 구성된 복합 자료형입니다.

// 객체 생성
let person = {
    name: "김철수",
    age: 30,
    city: "서울",
    isMarried: false,
    hobbies: ["독서", "영화감상", "요리"]
};

console.log(person.name);     // "김철수"
console.log(person["age"]);   // 30
console.log(person.hobbies);  // ["독서", "영화감상", "요리"]

🔑 객체 속성 접근 및 수정

let student = {
    name: "이영희",
    grade: 3,
    subjects: {
        math: 90,
        english: 85,
        science: 95
    }
};

// 속성 접근
console.log(student.name);           // "이영희"
console.log(student.subjects.math);  // 90

// 속성 수정
student.grade = 4;
student.subjects.math = 95;
console.log(student.grade);          // 4

// 새 속성 추가
student.age = 17;
student.subjects.history = 88;
console.log(student.age);            // 17

// 속성 삭제
delete student.age;
console.log(student.age);            // undefined

🔄 객체 메서드

// 메서드가 있는 객체
let calculator = {
    x: 10,
    y: 5,

    add: function() {
        return this.x + this.y;
    },

    // ES6 축약 문법
    subtract() {
        return this.x - this.y;
    },

    // 화살표 함수 (this 바인딩 주의)
    multiply: () => {
        // 화살표 함수는 this를 바인딩하지 않음
        return "this 접근 불가";
    }
};

console.log(calculator.add());      // 15
console.log(calculator.subtract()); // 5
console.log(calculator.multiply()); // "this 접근 불가"

🛠️ 객체 관련 유용한 메서드

let user = {
    id: 1,
    name: "김철수",
    email: "kim@example.com",
    role: "admin"
};

// Object.keys() - 키 배열
console.log(Object.keys(user));   // ["id", "name", "email", "role"]

// Object.values() - 값 배열
console.log(Object.values(user)); // [1, "김철수", "kim@example.com", "admin"]

// Object.entries() - [키, 값] 배열의 배열
console.log(Object.entries(user));
// [["id", 1], ["name", "김철수"], ["email", "kim@example.com"], ["role", "admin"]]

// Object.assign() - 객체 병합
let defaults = { theme: "light", language: "ko" };
let userSettings = { theme: "dark" };
let settings = Object.assign({}, defaults, userSettings);
console.log(settings); // { theme: "dark", language: "ko" }

// 스프레드 문법을 사용한 객체 병합 (ES6+)
let mergedSettings = { ...defaults, ...userSettings };
console.log(mergedSettings); // { theme: "dark", language: "ko" }

🎯 객체 실습 예제

// 상품 관리 시스템
class Product {
    constructor(id, name, price, category) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.category = category;
        this.createdAt = new Date();
    }

    getInfo() {
        return `${this.name} - ${this.formatPrice()}`;
    }

    formatPrice() {
        return new Intl.NumberFormat('ko-KR', {
            style: 'currency',
            currency: 'KRW'
        }).format(this.price);
    }

    isExpensive(threshold = 100000) {
        return this.price > threshold;
    }
}

// 사용 예제
const laptop = new Product(1, "MacBook Pro", 2500000, "Electronics");
console.log(laptop.getInfo());       // "MacBook Pro - ₩2,500,000"
console.log(laptop.isExpensive());   // true

// 객체 구조분해 할당
const { name, price, category } = laptop;
console.log(`${name}: ${price}원 (${category})`);

참조 자료형: 배열

📚 배열 기본

배열은 순서가 있는 값들의 집합입니다.

// 배열 생성
let numbers = [1, 2, 3, 4, 5];
let fruits = ["사과", "바나나", "오렌지"];
let mixed = [1, "문자열", true, null, {name: "김철수"}];

console.log(numbers[0]);    // 1
console.log(fruits.length); // 3
console.log(mixed[4].name); // "김철수"

🔧 배열 메서드

let arr = [1, 2, 3];

// 요소 추가/제거
arr.push(4);           // 끝에 추가: [1, 2, 3, 4]
arr.unshift(0);        // 앞에 추가: [0, 1, 2, 3, 4]
let last = arr.pop();  // 끝에서 제거: [0, 1, 2, 3], last = 4
let first = arr.shift(); // 앞에서 제거: [1, 2, 3], first = 0

console.log(arr);   // [1, 2, 3]
console.log(last);  // 4
console.log(first); // 0

// 배열 분할/병합
let sliced = arr.slice(1, 3);     // [2, 3] (원본 변경 없음)
let spliced = arr.splice(1, 1, 'NEW'); // [2] (원본에서 제거하고 'NEW' 삽입)
console.log(arr);     // [1, 'NEW', 3]
console.log(spliced); // [2]

// 배열 합치기
let arr1 = [1, 2];
let arr2 = [3, 4];
let combined = arr1.concat(arr2);     // [1, 2, 3, 4]
let spread = [...arr1, ...arr2];      // [1, 2, 3, 4]
console.log(combined);
console.log(spread);

🔄 배열 반복 메서드

let numbers = [1, 2, 3, 4, 5];

// forEach - 각 요소에 대해 함수 실행
numbers.forEach((num, index) => {
    console.log(`${index}: ${num}`);
});

// map - 새로운 배열 생성
let doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter - 조건에 맞는 요소만 필터링
let evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]

// find - 조건에 맞는 첫 번째 요소
let found = numbers.find(num => num > 3);
console.log(found); // 4

// reduce - 배열을 하나의 값으로 줄이기
let sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15

// some/every - 조건 검사
let hasEven = numbers.some(num => num % 2 === 0);
let allPositive = numbers.every(num => num > 0);
console.log(hasEven);     // true
console.log(allPositive); // true

📊 배열 실습 예제

// 학생 점수 관리 시스템
class GradeManager {
    constructor() {
        this.students = [];
    }

    addStudent(name, scores) {
        const student = {
            name,
            scores,
            average: this.calculateAverage(scores),
            grade: this.getGrade(this.calculateAverage(scores))
        };
        this.students.push(student);
        return student;
    }

    calculateAverage(scores) {
        return scores.reduce((sum, score) => sum + score, 0) / scores.length;
    }

    getGrade(average) {
        if (average >= 90) return 'A';
        if (average >= 80) return 'B';
        if (average >= 70) return 'C';
        if (average >= 60) return 'D';
        return 'F';
    }

    getTopStudents(count = 3) {
        return this.students
            .sort((a, b) => b.average - a.average)
            .slice(0, count);
    }

    getStatistics() {
        const averages = this.students.map(s => s.average);
        return {
            count: this.students.length,
            min: Math.min(...averages),
            max: Math.max(...averages),
            average: averages.reduce((sum, avg) => sum + avg, 0) / averages.length
        };
    }
}

// 사용 예제
const gradeManager = new GradeManager();

gradeManager.addStudent("김철수", [95, 87, 92]);
gradeManager.addStudent("이영희", [88, 94, 90]);
gradeManager.addStudent("박민수", [76, 82, 79]);

console.log("상위 2명:", gradeManager.getTopStudents(2));
console.log("통계:", gradeManager.getStatistics());

함수 자료형

🔧 함수도 자료형입니다

JavaScript에서 함수는 일급 객체로, 변수에 할당하고 다른 함수의 인수로 전달할 수 있습니다.

// 함수 선언문
function greet(name) {
    return `안녕하세요, ${name}님!`;
}

// 함수 표현식
const add = function(a, b) {
    return a + b;
};

// 화살표 함수
const multiply = (a, b) => a * b;

// 함수를 변수에 저장
let myFunction = greet;
console.log(myFunction("김철수")); // "안녕하세요, 김철수님!"

// 함수를 배열에 저장
let operations = [add, multiply];
console.log(operations[0](5, 3)); // 8
console.log(operations[1](5, 3)); // 15

🔗 고차 함수 (Higher-Order Functions)

// 함수를 인수로 받는 함수
function calculate(operation, a, b) {
    return operation(a, b);
}

const add = (x, y) => x + y;
const subtract = (x, y) => x - y;

console.log(calculate(add, 10, 5));      // 15
console.log(calculate(subtract, 10, 5)); // 5

// 함수를 반환하는 함수
function createMultiplier(factor) {
    return function(number) {
        return number * factor;
    };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(4));  // 8
console.log(triple(4));  // 12

typeof 연산자

🔍 typeof 사용법

// 원시 자료형
console.log(typeof "Hello");         // "string"
console.log(typeof 42);              // "number"
console.log(typeof true);            // "boolean"
console.log(typeof undefined);       // "undefined"
console.log(typeof Symbol("id"));    // "symbol"
console.log(typeof 123n);            // "bigint"

// 참조 자료형
console.log(typeof null);            // "object" (잘알린 버그)
console.log(typeof {});              // "object"
console.log(typeof []);              // "object"
console.log(typeof function(){});    // "function"
console.log(typeof new Date());      // "object"

🎯 정확한 타입 확인 방법

// 더 정확한 타입 확인 함수
function getType(value) {
    return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}

console.log(getType(null));           // "null"
console.log(getType([]));             // "array"
console.log(getType({}));             // "object"
console.log(getType(new Date()));     // "date"
console.log(getType(/regex/));        // "regexp"

// 배열 확인
console.log(Array.isArray([]));       // true
console.log(Array.isArray({}));       // false

// 특정 타입 확인 함수들
function isString(value) { return typeof value === 'string'; }
function isNumber(value) { return typeof value === 'number' && !isNaN(value); }
function isFunction(value) { return typeof value === 'function'; }
function isObject(value) { return value !== null && typeof value === 'object' && !Array.isArray(value); }

자료형 변환

🔄 명시적 변환 (Explicit Conversion)

// 문자열로 변환
let num = 123;
console.log(String(num));        // "123"
console.log(num.toString());     // "123"
console.log(`${num}`);          // "123"

// 숫자로 변환
let str = "456";
console.log(Number(str));        // 456
console.log(parseInt(str));      // 456
console.log(parseFloat("45.6")); // 45.6
console.log(+"789");            // 789 (단항 + 연산자)

// 불린으로 변환
console.log(Boolean(1));         // true
console.log(Boolean(0));         // false
console.log(!!"Hello");         // true (이중 부정)

⚡ 암시적 변환 (Implicit Conversion)

// 문자열 연결
console.log("5" + 3);           // "53" (문자열로 변환)
console.log(3 + "5");           // "35"

// 숫자 연산
console.log("5" - 3);           // 2 (숫자로 변환)
console.log("5" * 2);           // 10
console.log("10" / 2);          // 5

// 불린 컨텍스트
if ("") {                       // falsy
    console.log("실행되지 않음");
}

if ("Hello") {                  // truthy
    console.log("실행됨");       // 실행됨
}

// 비교 연산
console.log("5" == 5);          // true (타입 변환 후 비교)
console.log("5" === 5);         // false (타입 변환 없이 비교)

⚠️ 변환 시 주의점

// 의도하지 않은 변환
console.log([] + []);           // "" (빈 문자열)
console.log([] + {});           // "[object Object]"
console.log({} + []);           // "[object Object]"

// NaN 생성 경우
console.log(Number("Hello"));   // NaN
console.log(parseInt("abc"));   // NaN
console.log(0 / 0);             // NaN

// 안전한 숫자 변환
function safeNumber(value, defaultValue = 0) {
    const converted = Number(value);
    return isNaN(converted) ? defaultValue : converted;
}

console.log(safeNumber("123"));     // 123
console.log(safeNumber("abc"));     // 0
console.log(safeNumber("abc", -1)); // -1

실무 활용 팁

🛡️ 자료형 검증

// 입력값 검증 함수
const Validator = {
    isValidEmail(email) {
        return typeof email === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    },

    isValidAge(age) {
        return typeof age === 'number' && age >= 0 && age <= 150 && Number.isInteger(age);
    },

    isValidArray(arr, minLength = 0) {
        return Array.isArray(arr) && arr.length >= minLength;
    },

    isValidObject(obj) {
        return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
    }
};

// 사용 예제
console.log(Validator.isValidEmail("user@example.com")); // true
console.log(Validator.isValidAge(25));                   // true
console.log(Validator.isValidArray([1, 2, 3], 2));       // true

🔄 자료형 유틸리티

// 자료형 유틸리티 객체
const TypeUtils = {
    // 깊은 복사
    deepClone(obj) {
        if (obj === null || typeof obj !== 'object') return obj;
        if (obj instanceof Date) return new Date(obj);
        if (obj instanceof Array) return obj.map(item => this.deepClone(item));

        const cloned = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                cloned[key] = this.deepClone(obj[key]);
            }
        }
        return cloned;
    },

    // 객체 병합 (깊은 병합)
    deepMerge(target, source) {
        const merged = this.deepClone(target);

        for (let key in source) {
            if (source.hasOwnProperty(key)) {
                if (this.isObject(source[key]) && this.isObject(merged[key])) {
                    merged[key] = this.deepMerge(merged[key], source[key]);
                } else {
                    merged[key] = source[key];
                }
            }
        }
        return merged;
    },

    // 객체 검사
    isObject(value) {
        return value !== null && typeof value === 'object' && !Array.isArray(value);
    },

    // 빈 값 검사
    isEmpty(value) {
        if (value === null || value === undefined) return true;
        if (typeof value === 'string') return value.trim() === '';
        if (Array.isArray(value)) return value.length === 0;
        if (this.isObject(value)) return Object.keys(value).length === 0;
        return false;
    }
};

// 사용 예제
const original = { a: 1, b: { c: 2 } };
const cloned = TypeUtils.deepClone(original);
cloned.b.c = 3;
console.log(original.b.c); // 2 (원본 유지)
console.log(cloned.b.c);   // 3

📊 데이터 처리 예제

// 실제 데이터 처리 시나리오
class DataProcessor {
    constructor() {
        this.data = [];
    }

    // 다양한 자료형의 데이터 수집
    collectData(input) {
        // 입력 데이터 정규화
        if (typeof input === 'string') {
            try {
                input = JSON.parse(input);
            } catch (e) {
                input = { value: input, type: 'string' };
            }
        }

        if (typeof input === 'number') {
            input = { value: input, type: 'number' };
        }

        if (Array.isArray(input)) {
            input = { value: input, type: 'array', length: input.length };
        }

        this.data.push({
            ...input,
            timestamp: new Date(),
            id: this.generateId()
        });
    }

    // 데이터 분석
    analyze() {
        const typeStats = this.data.reduce((stats, item) => {
            const type = item.type || 'unknown';
            stats[type] = (stats[type] || 0) + 1;
            return stats;
        }, {});

        return {
            total: this.data.length,
            types: typeStats,
            latest: this.data[this.data.length - 1],
            summary: this.generateSummary()
        };
    }

    generateId() {
        return Date.now().toString(36) + Math.random().toString(36).substr(2);
    }

    generateSummary() {
        const values = this.data
            .filter(item => typeof item.value === 'number')
            .map(item => item.value);

        if (values.length === 0) {
            return { message: "숫자 데이터가 없습니다" };
        }

        return {
            count: values.length,
            sum: values.reduce((a, b) => a + b, 0),
            average: values.reduce((a, b) => a + b, 0) / values.length,
            min: Math.min(...values),
            max: Math.max(...values)
        };
    }
}

// 사용 예제
const processor = new DataProcessor();

processor.collectData(42);
processor.collectData("Hello World");
processor.collectData([1, 2, 3, 4, 5]);
processor.collectData({ name: "김철수", age: 30 });
processor.collectData('{"price": 1000, "currency": "KRW"}');

console.log(processor.analyze());

마무리

JavaScript의 자료형을 이해하는 것은 프로그래밍의 기본 중의 기본입니다. 각 자료형의 특징과 사용법을 정확히 아는 것이 버그 없는 코드를 작성하는 첫걸음입니다.

✅ 핵심 정리

  1. 원시 자료형: String, Number, Boolean, undefined, null, Symbol, BigInt
  2. 참조 자료형: Object, Array, Function
  3. 타입 검사: typeof, Array.isArray(), Object.prototype.toString.call()
  4. 타입 변환: 명시적 변환과 암시적 변환 구분

🚀 실무 활용 포인트

  1. 타입 검증: 함수 입력값 검증으로 안정성 확보
  2. 적절한 자료형 선택: 상황에 맞는 자료형 사용
  3. 타입 변환 주의: 의도하지 않은 변환 방지
  4. 불변성 고려: 원시 자료형의 불변성 활용

JavaScript 자료형을 제대로 이해했다면, 이제 더 복잡한 프로그래밍 개념을 학습할 준비가 되었습니다. 실제 프로젝트에서 다양한 자료형을 활용해보며 경험을 쌓아가세요!

자료형에 대한 설명이 도움이 되셨나요? 궁금한 점이나 실습 중 어려운 부분이 있다면 댓글로 남겨주세요! 💬