프론트엔드 짧은 간단 지식 정리 - 알아놓으면 좋은 자바스크립트 문법

이상범·2024년 9월 25일

1. Shorthand Property Names 🎯

객체를 더 간결하게 작성하는 방법입니다.

🔍 정의

변수명과 객체의 키(key) 이름이 같을 때, 축약 표기법을 사용할 수 있습니다.

💡 기본 사용법

// ❌ 기존 방식: 중복되는 이름
const name = "Alice";
const age = 25;
const city = "Seoul";

const user1 = {
    name: name,
    age: age,
    city: city
};

// ✅ Shorthand Property Names: 간결한 표현
const user2 = {
    name,  // name: name
    age,   // age: age
    city   // city: city
};

console.log(user2); // { name: 'Alice', age: 25, city: 'Seoul' }

🌟 실전 활용

// API 응답 데이터 생성
function createResponse(status, data, message) {
    return {
        status,    // status: status
        data,      // data: data
        message,   // message: message
        timestamp: Date.now()
    };
}

const response = createResponse(200, { id: 1 }, "Success");
console.log(response);
// {
//   status: 200,
//   data: { id: 1 },
//   message: 'Success',
//   timestamp: 1234567890
// }
// 함수에서 객체 반환
function getUserInfo() {
    const id = 1;
    const name = "Bob";
    const email = "bob@example.com";
    
    return { id, name, email }; // 간결한 반환
}

console.log(getUserInfo());
// { id: 1, name: 'Bob', email: 'bob@example.com' }

2. Destructuring Assignment 📦

객체나 배열에서 값을 추출하는 강력한 문법입니다.

🔍 정의

구조 분해 할당(Destructuring Assignment)은 객체의 속성이나 배열의 요소를 개별 변수로 쉽게 추출할 수 있게 해줍니다.

💡 객체 구조 분해

기본 사용법

const user = {
    name: "Alice",
    age: 25,
    city: "Seoul"
};

// ❌ 기존 방식
const name = user.name;
const age = user.age;
const city = user.city;

// ✅ 구조 분해 할당
const { name, age, city } = user;
console.log(name, age, city); // "Alice" 25 "Seoul"

변수명 변경

const user = { name: "Bob", age: 30 };

// 다른 이름의 변수로 할당
const { name: userName, age: userAge } = user;
console.log(userName, userAge); // "Bob" 30

기본값 설정

const user = { name: "Charlie" };

// age가 없으면 기본값 사용
const { name, age = 20, city = "Unknown" } = user;
console.log(name, age, city); // "Charlie" 20 "Unknown"

중첩 객체 구조 분해

const user = {
    name: "David",
    address: {
        city: "Seoul",
        country: "Korea"
    }
};

const { 
    name, 
    address: { city, country } 
} = user;

console.log(name, city, country); // "David" "Seoul" "Korea"

💡 배열 구조 분해

기본 사용법

const colors = ["red", "green", "blue"];

// ❌ 기존 방식
const color1 = colors[0];
const color2 = colors[1];
const color3 = colors[2];

// ✅ 구조 분해 할당
const [first, second, third] = colors;
console.log(first, second, third); // "red" "green" "blue"

일부 요소만 추출

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

// 필요한 요소만 추출
const [first, , third, , fifth] = numbers;
console.log(first, third, fifth); // 1 3 5

Rest 패턴

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

const [first, second, ...rest] = numbers;
console.log(first);  // 1
console.log(second); // 2
console.log(rest);   // [3, 4, 5]

기본값 설정

const [a = 1, b = 2, c = 3] = [10, 20];
console.log(a, b, c); // 10 20 3

🌟 실전 활용

// 1. 함수 매개변수에서 구조 분해
function printUser({ name, age, city = "Seoul" }) {
    console.log(`${name}${age}살이고 ${city}에 살고 있습니다.`);
}

printUser({ name: "Alice", age: 25 });
// "Alice은 25살이고 Seoul에 살고 있습니다."

// 2. 배열 교환
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1

// 3. 함수에서 여러 값 반환
function getUser() {
    return {
        id: 1,
        name: "Bob",
        email: "bob@example.com"
    };
}

const { id, name, email } = getUser();
console.log(id, name, email); // 1 "Bob" "bob@example.com"

3. Spread Syntax 🌊

객체나 배열을 펼쳐서 복사하거나 병합하는 연산자입니다.

🔍 정의

Spread 연산자(...)는 배열이나 객체의 요소를 개별 요소로 펼칩니다.

💡 배열에서 사용

// 배열 복사
const arr1 = [1, 2, 3];
const arr2 = [...arr1];

arr2.push(4);
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [1, 2, 3, 4]

// 배열 병합
const arr3 = [1, 2];
const arr4 = [3, 4];
const merged = [...arr3, ...arr4];
console.log(merged); // [1, 2, 3, 4]

// 배열 중간에 요소 추가
const arr5 = [1, 2, 5];
const arr6 = [1, 2, 3, 4, 5];
console.log([...arr3, 3, 4, ...arr5]); // [1, 2, 3, 4, 1, 2, 5]

💡 객체에서 사용

// 객체 복사
const obj1 = { name: "Alice", age: 25 };
const obj2 = { ...obj1 };

obj2.age = 30;
console.log(obj1); // { name: "Alice", age: 25 }
console.log(obj2); // { name: "Alice", age: 30 }

// 객체 병합
const user = { name: "Bob" };
const details = { age: 30, city: "Seoul" };
const fullUser = { ...user, ...details };
console.log(fullUser);
// { name: "Bob", age: 30, city: "Seoul" }

// 속성 덮어쓰기
const original = { x: 1, y: 2 };
const updated = { ...original, y: 3, z: 4 };
console.log(updated); // { x: 1, y: 3, z: 4 }

⚠️ 주의사항: 얕은 복사

// 1 depth는 깊은 복사
const obj1 = { key: "1" };
const obj2 = { key2: "2" };
const merge = { ...obj1, ...obj2 };

merge.key2 = 100;
console.log(obj2);  // { key2: "2" } ✅ 원본 유지
console.log(merge); // { key: "1", key2: 100 }

// 2 depth부터는 얕은 복사
const original = {
    user: {
        name: "Alice",
        age: 25
    }
};

const copy = { ...original };
copy.user.age = 30; // 중첩 객체는 참조 유지

console.log(original.user.age); // 30 ⚠️ 원본도 변경됨!

🌟 실전 활용

// 1. 함수 인자로 배열 전달
function sum(a, b, c) {
    return a + b + c;
}

const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6

// 2. 배열 합치기
const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [5, 6];
const combined = [...arr1, ...arr2, ...arr3];
console.log(combined); // [1, 2, 3, 4, 5, 6]

// 3. 불변성 유지하며 상태 업데이트
const state = {
    user: { name: "Alice" },
    count: 0
};

const newState = {
    ...state,
    count: state.count + 1
};
console.log(newState); // { user: { name: "Alice" }, count: 1 }

4. Default Parameters 🎛️

함수 매개변수의 기본값을 설정하는 방법입니다.

🔍 정의

함수 호출 시 인자가 전달되지 않거나 undefined일 때 사용할 기본값을 설정합니다.

💡 기본 사용법

// ❌ 기존 방식
function greet(name) {
    name = name || "Guest";
    console.log(`Hello, ${name}!`);
}

// ✅ Default Parameters
function greet(name = "Guest") {
    console.log(`Hello, ${name}!`);
}

greet();          // "Hello, Guest!"
greet("Alice");   // "Hello, Alice!"
greet(undefined); // "Hello, Guest!"
greet(null);      // "Hello, null!" ⚠️ null은 기본값 X

🌟 실전 활용

// 1. 여러 기본값 설정
function createUser(name = "Anonymous", age = 0, city = "Unknown") {
    return { name, age, city };
}

console.log(createUser());
// { name: "Anonymous", age: 0, city: "Unknown" }

console.log(createUser("Alice", 25));
// { name: "Alice", age: 25, city: "Unknown" }

// 2. 표현식을 기본값으로 사용
function getDefaultName() {
    return "Guest_" + Math.random().toString(36).substr(2, 9);
}

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

greet(); // "Hello, Guest_a8xc9k2!"

// 3. 이전 매개변수 참조
function createRectangle(width = 10, height = width * 2) {
    return { width, height };
}

console.log(createRectangle());     // { width: 10, height: 20 }
console.log(createRectangle(5));    // { width: 5, height: 10 }
console.log(createRectangle(5, 8)); // { width: 5, height: 8 }

// 4. 객체 구조 분해와 함께 사용
function printUser({ name = "Anonymous", age = 0 } = {}) {
    console.log(`${name} (${age}세)`);
}

printUser();                        // "Anonymous (0세)"
printUser({ name: "Alice" });       // "Alice (0세)"
printUser({ name: "Bob", age: 30 }); // "Bob (30세)"

5. Ternary Operator 🔀

조건문을 한 줄로 표현하는 연산자입니다.

🔍 정의

삼항 연산자는 조건 ? 참일값 : 거짓일값 형태로 사용합니다.

💡 기본 사용법

// ❌ 기존 방식
let message;
const isLoggedIn = true;

if (isLoggedIn) {
    message = "Welcome!";
} else {
    message = "Please log in";
}

// ✅ Ternary Operator
const message = isLoggedIn ? "Welcome!" : "Please log in";
console.log(message); // "Welcome!"

🌟 실전 활용

// 1. 변수 할당
const age = 20;
const isAdult = age >= 18 ? true : false;
console.log(isAdult); // true

// 2. 함수 반환값
function getGreeting(hour) {
    return hour < 12 ? "Good morning! 🌅" : "Good afternoon! 🌞";
}
console.log(getGreeting(10)); // "Good morning! 🌅"
console.log(getGreeting(15)); // "Good afternoon! 🌞"

// 3. 중첩 삼항 연산자 (권장하지 않음)
const score = 85;
const grade = score >= 90 ? "A" : 
              score >= 80 ? "B" : 
              score >= 70 ? "C" : "F";
console.log(grade); // "B"

// 4. JSX에서 조건부 렌더링 (React)
const isLoading = false;
const content = isLoading ? <Spinner /> : <Content />;

// 5. 배열 메서드와 함께
const numbers = [1, 2, 3, 4, 5];
const evenOrOdd = numbers.map(num => 
    num % 2 === 0 ? "짝수" : "홀수"
);
console.log(evenOrOdd); // ["홀수", "짝수", "홀수", "짝수", "홀수"]

⚠️ 주의사항

// ❌ 너무 복잡한 중첩은 가독성 저하
const result = condition1 ? 
    (condition2 ? value1 : value2) : 
    (condition3 ? value3 : value4);

// ✅ 복잡한 로직은 if-else 사용
if (condition1) {
    if (condition2) {
        result = value1;
    } else {
        result = value2;
    }
} else if (condition3) {
    result = value3;
} else {
    result = value4;
}

6. Template Literals 📝

문자열을 더 편리하게 다루는 방법입니다.

🔍 정의

템플릿 리터럴은 백틱(`)을 사용하여 문자열 안에 변수나 표현식을 쉽게 삽입할 수 있습니다.

💡 기본 사용법

const name = "Alice";
const age = 25;

// ❌ 기존 방식
const message1 = "Hello, " + name + "! You are " + age + " years old.";

// ✅ Template Literals
const message2 = `Hello, ${name}! You are ${age} years old.`;
console.log(message2); // "Hello, Alice! You are 25 years old."

🌟 실전 활용

// 1. 여러 줄 문자열
const multiLine = `
    This is line 1
    This is line 2
    This is line 3
`;
console.log(multiLine);

// 2. 표현식 사용
const a = 10;
const b = 20;
console.log(`${a} + ${b} = ${a + b}`); // "10 + 20 = 30"

// 3. 함수 호출
function getPrice(price) {
    return price.toLocaleString();
}

const product = "Laptop";
const price = 1500000;
console.log(`${product}: ${getPrice(price)}`);
// "Laptop: 1,500,000원"

// 4. 중첩 템플릿
const isLoggedIn = true;
const userName = "Bob";
const greeting = `Hello, ${isLoggedIn ? `${userName}!` : "Guest!"}`;
console.log(greeting); // "Hello, Bob!"

// 5. HTML 템플릿 생성
const user = { name: "Charlie", email: "charlie@example.com" };
const html = `
    <div class="user-card">
        <h2>${user.name}</h2>
        <p>${user.email}</p>
    </div>
`;
console.log(html);

🎨 Tagged Templates (고급)

// 커스텀 템플릿 처리
function highlight(strings, ...values) {
    return strings.reduce((result, str, i) => {
        return `${result}${str}<strong>${values[i] || ""}</strong>`;
    }, "");
}

const name = "Alice";
const age = 25;
const result = highlight`Name: ${name}, Age: ${age}`;
console.log(result);
// "Name: <strong>Alice</strong>, Age: <strong>25</strong>"

7. Optional Chaining ⛓️

안전하게 중첩된 속성에 접근하는 방법입니다.

🔍 정의

Optional Chaining(?.)은 객체의 속성이 존재하지 않을 때 에러 대신 undefined를 반환합니다.

💡 기본 사용법

const user = {
    name: "Alice",
    address: {
        city: "Seoul"
    }
};

// ❌ 기존 방식: 에러 발생 가능
// console.log(user.profile.bio); // TypeError!

// ❌ 기존 방식: 복잡한 체크
if (user && user.profile && user.profile.bio) {
    console.log(user.profile.bio);
}

// ✅ Optional Chaining
console.log(user.profile?.bio); // undefined (에러 없음!)
console.log(user.address?.city); // "Seoul"

🌟 실전 활용

// 1. 깊은 중첩 객체 접근
const person = {
    name: "Bob",
    contact: {
        email: "bob@example.com",
        phone: {
            mobile: "010-1234-5678"
        }
    }
};

// 안전한 접근
console.log(person.contact?.phone?.mobile); // "010-1234-5678"
console.log(person.contact?.address?.city); // undefined

// 2. 배열 요소 접근
const users = [
    { name: "Alice", age: 25 },
    { name: "Bob", age: 30 }
];

console.log(users[0]?.name);  // "Alice"
console.log(users[5]?.name);  // undefined
console.log(users?.[0]?.age); // 25

// 3. 함수 호출
const obj = {
    greet: () => "Hello!"
};

console.log(obj.greet?.()); // "Hello!"
console.log(obj.sayBye?.()); // undefined (에러 없음)

// 4. Nullish Coalescing과 함께 사용
const city = person.address?.city ?? "Unknown";
console.log(city); // "Unknown"

🎯 실무 예시

// API 응답 처리
const apiResponse = {
    data: {
        user: {
            profile: {
                name: "Charlie",
                avatar: {
                    url: "https://example.com/avatar.jpg"
                }
            }
        }
    }
};

// 안전한 데이터 추출
const avatarUrl = apiResponse?.data?.user?.profile?.avatar?.url;
console.log(avatarUrl); // "https://example.com/avatar.jpg"

// 존재하지 않는 데이터도 안전하게
const bio = apiResponse?.data?.user?.profile?.bio ?? "No bio available";
console.log(bio); // "No bio available"

8. Nullish Coalescing Operator 🎯

null/undefined를 확실하게 체크하는 연산자입니다.

🔍 정의

Nullish Coalescing Operator(??)는 왼쪽 값이 null 또는 undefined일 때만 오른쪽 값을 반환합니다.

💡 OR 연산자(||)와의 차이

// || 연산자: falsy 값 모두 체크
const value1 = 0 || "default";
console.log(value1); // "default" (0은 falsy)

const value2 = "" || "default";
console.log(value2); // "default" (빈 문자열은 falsy)

// ?? 연산자: null/undefined만 체크
const value3 = 0 ?? "default";
console.log(value3); // 0 ✅

const value4 = "" ?? "default";
console.log(value4); // "" ✅

const value5 = null ?? "default";
console.log(value5); // "default"

const value6 = undefined ?? "default";
console.log(value6); // "default"

🌟 실전 활용

// 1. 설정값 기본값 처리
const config = {
    timeout: 0,        // 0은 유효한 값
    retries: null,     // null은 설정되지 않음
    cache: false,      // false는 유효한 값
    endpoint: ""       // 빈 문자열도 유효한 값
};

const timeout = config.timeout ?? 3000;
const retries = config.retries ?? 3;
const cache = config.cache ?? true;
const endpoint = config.endpoint ?? "https://api.example.com";

console.log(timeout);  // 0 (설정값 유지)
console.log(retries);  // 3 (기본값 사용)
console.log(cache);    // false (설정값 유지)
console.log(endpoint); // "" (빈 문자열 유지)

// 2. 사용자 입력 처리
function createUser(name, age, score) {
    return {
        name: name ?? "Anonymous",
        age: age ?? 0,         // 0살도 유효
        score: score ?? 0      // 0점도 유효
    };
}

console.log(createUser("Alice", 0, 0));
// { name: "Alice", age: 0, score: 0 } ✅

console.log(createUser(null, null, null));
// { name: "Anonymous", age: 0, score: 0 }

// 3. Optional Chaining과 함께
const user = {
    profile: {
        bio: ""  // 빈 문자열도 유효한 bio
    }
};

const bio = user.profile?.bio ?? "No bio provided";
console.log(bio); // "" (빈 문자열 유지)

const location = user.profile?.location ?? "Unknown";
console.log(location); // "Unknown"

📊 비교 표

\| 결과?? 결과
0오른쪽 값0 (왼쪽 값)
""오른쪽 값"" (왼쪽 값)
false오른쪽 값false (왼쪽 값)
null오른쪽 값오른쪽 값
undefined오른쪽 값오른쪽 값
NaN오른쪽 값NaN (왼쪽 값)

🎯 언제 사용할까?

// ✅ ?? 사용: 0, "", false가 유효한 값인 경우
const count = userInput ?? 10;      // 0도 허용
const name = userName ?? "Guest";   // 빈 문자열도 허용
const enabled = isEnabled ?? true;  // false도 허용

// ✅ || 사용: falsy 값을 모두 기본값으로 대체하고 싶은 경우
const displayName = userName || "Guest"; // 빈 문자열은 "Guest"로

9. 실전 종합 예제 🚀

모든 문법을 활용한 실무 코드 예시입니다.

🎯 사용자 관리 시스템

// API 응답 데이터 생성
function createUserResponse(
    userId,
    userData = {},
    options = {}
) {
    // Destructuring + Default Parameters
    const {
        name = "Anonymous",
        age = 0,
        email = null,
        address = {}
    } = userData;
    
    const {
        includeTimestamp = true,
        format = "json"
    } = options;
    
    // Shorthand Property Names + Spread Syntax
    const response = {
        userId,
        user: {
            name,
            age,
            email: email ?? "No email provided",
            ...address
        },
        ...(includeTimestamp && { timestamp: Date.now() })
    };
    
    // Template Literals + Ternary Operator
    return format === "json"
        ? JSON.stringify(response, null, 2)
        : `User: ${name} (${age}세)`;
}

// 사용 예시
const result = createUserResponse(
    123,
    {
        name: "Alice",
        age: 25,
        address: { city: "Seoul", country: "Korea" }
    },
    { includeTimestamp: true }
);

console.log(result);
/*
{
  "userId": 123,
  "user": {
    "name": "Alice",
    "age": 25,
    "email": "No email provided",
    "city": "Seoul",
    "country": "Korea"
  },
  "timestamp": 1234567890
}
*/

🛒 쇼핑몰 장바구니

class ShoppingCart {
    constructor() {
        this.items = [];
    }
    
    // 상품 추가
    addItem(product) {
        const {
            id,
            name,
            price = 0,
            quantity = 1,
            discount = 0
        } = product;
        
        // Optional Chaining + Nullish Coalescing
        const existingItem = this.items.find(item => item.id === id);
        
        if (existingItem) {
            existingItem.quantity += quantity;
        } else {
            this.items.push({ id, name, price, quantity, discount });
        }
        
        return this;
    }
    
    // 총 금액 계산
    getTotal() {
        return this.items.reduce((total, item) => {
            const { price, quantity, discount = 0 } = item;
            const itemTotal = price * quantity * (1 - discount / 100);
            return total + itemTotal;
        }, 0);
    }
    
    // 장바구니 요약
    getSummary() {
        const total = this.getTotal();
        const itemCount = this.items.reduce((sum, item) => 
            sum + item.quantity, 0
        );
        
        return `
            🛒 장바구니 요약
            ----------------
            총 상품 수: ${itemCount}개
            총 금액: ${total.toLocaleString()}원
            
            상품 목록:
            ${this.items.map(item => 
                `- ${item.name}: ${item.quantity}개 (${item.price.toLocaleString()}원)`
            ).join('\n            ')}
        `;
    }
}

// 사용 예시
const cart = new ShoppingCart();

cart
    .addItem({ id: 1, name: "노트북", price: 1500000, quantity: 1, discount: 10 })
    .addItem({ id: 2, name: "마우스", price: 50000, quantity: 2 })
    .addItem({ id: 3, name: "키보드", price: 100000, quantity: 1 });

console.log(cart.getSummary());
/*
🛒 장바구니 요약
----------------
총 상품 수: 4개
총 금액: 1,600,000원

상품 목록:
- 노트북: 1개 (1,500,000원)
- 마우스: 2개 (50,000원)
- 키보드: 1개 (100,000원)
*/

📊 데이터 처리 유틸리티

// API 데이터 정규화
function normalizeApiData(apiResponse) {
    // Optional Chaining으로 안전한 접근
    const data = apiResponse?.data ?? [];
    
    return data.map(item => {
        // Destructuring + Default Values
        const {
            id,
            name = "Unknown",
            email = null,
            isActive = false,
            metadata = {}
        } = item;
        
        // Spread + Shorthand
        return {
            id,
            name,
            email: email ?? "no-email@example.com",
            status: isActive ? "active" : "inactive",
            ...metadata,
            // Template Literals
            displayName: `${name} (${id})`
        };
    });
}

// 사용 예시
const apiResponse = {
    data: [
        { id: 1, name: "Alice", email: "alice@example.com", isActive: true },
        { id: 2, name: "Bob", isActive: false },
        { id: 3, email: null, metadata: { role: "admin" } }
    ]
};

const normalized = normalizeApiData(apiResponse);
console.log(normalized);
/*
[
  {
    id: 1,
    name: "Alice",
    email: "alice@example.com",
    status: "active",
    displayName: "Alice (1)"
  },
  {
    id: 2,
    name: "Bob",
    email: "no-email@example.com",
    status: "inactive",
    displayName: "Bob (2)"
  },
  {
    id: 3,
    name: "Unknown",
    email: "no-email@example.com",
    status: "inactive",
    role: "admin",
    displayName: "Unknown (3)"
  }
]
*/

🎨 설정 관리자

class ConfigManager {
    constructor(defaultConfig = {}) {
        // Spread로 기본 설정 복사
        this.config = {
            theme: "light",
            language: "ko",
            notifications: true,
            autoSave: false,
            timeout: 30000,
            ...defaultConfig
        };
    }
    
    // 설정 값 가져오기
    get(key, fallback = null) {
        // Optional Chaining + Nullish Coalescing
        return this.config?.[key] ?? fallback;
    }
    
    // 설정 업데이트
    update(updates = {}) {
        // Spread로 불변성 유지
        this.config = {
            ...this.config,
            ...updates
        };
        return this;
    }
    
    // 설정 초기화
    reset(keys = []) {
        if (keys.length === 0) {
            // 전체 초기화
            this.config = {
                theme: "light",
                language: "ko",
                notifications: true,
                autoSave: false,
                timeout: 30000
            };
        } else {
            // 특정 키만 초기화
            keys.forEach(key => {
                const defaults = {
                    theme: "light",
                    language: "ko",
                    notifications: true,
                    autoSave: false,
                    timeout: 30000
                };
                this.config[key] = defaults[key];
            });
        }
        return this;
    }
    
    // 설정 출력
    toString() {
        const { theme, language, notifications, autoSave, timeout } = this.config;
        
        return `
⚙️  현재 설정
--------------
테마: ${theme}
언어: ${language}
알림: ${notifications ? "켜짐" : "꺼짐"}
자동 저장: ${autoSave ? "켜짐" : "꺼짐"}
타임아웃: ${timeout}ms
        `.trim();
    }
}

// 사용 예시
const config = new ConfigManager({ theme: "dark" });

console.log(config.toString());
/*
⚙️  현재 설정
--------------
테마: dark
언어: ko
알림: 켜짐
자동 저장: 꺼짐
타임아웃: 30000ms
*/

config.update({ autoSave: true, timeout: 60000 });
console.log(config.get("autoSave")); // true
console.log(config.get("maxRetries", 3)); // 3 (fallback)

10. 마무리 🎉

🌟 핵심 정리

문법기호용도예시
Shorthand Property-객체 속성 축약{ name, age }
Destructuring{ } [ ]구조 분해 할당const { name } = obj
Spread...배열/객체 펼치기{ ...obj }
Default Parameters=기본값 설정function(x = 0)
Ternary? :삼항 연산자a ? b : c
Template Literals`문자열 템플릿`Hello ${name}`
Optional Chaining?.안전한 접근obj?.prop
Nullish Coalescing??null/undefined 체크value ?? default

🚀 실무 활용 팁

1️⃣ 깔끔한 코드 작성

// ❌ 읽기 어려운 코드
function processUser(user) {
    var name;
    if (user && user.profile && user.profile.name) {
        name = user.profile.name;
    } else {
        name = "Anonymous";
    }
    
    var age;
    if (user && user.profile && user.profile.age) {
        age = user.profile.age;
    } else {
        age = 0;
    }
    
    return { name: name, age: age };
}

// ✅ 깔끔한 코드
function processUser(user) {
    const name = user?.profile?.name ?? "Anonymous";
    const age = user?.profile?.age ?? 0;
    return { name, age };
}

2️⃣ 불변성 유지

// ❌ 원본 수정
function updateUser(user, updates) {
    user.name = updates.name;
    user.age = updates.age;
    return user; // 원본이 수정됨!
}

// ✅ 새 객체 반환
function updateUser(user, updates) {
    return { ...user, ...updates };
}

3️⃣ 안전한 데이터 접근

// ❌ 에러 발생 가능
function getCity(user) {
    return user.address.city; // user.address가 없으면 에러!
}

// ✅ 안전한 접근
function getCity(user) {
    return user?.address?.city ?? "Unknown";
}

💡 조합해서 사용하기

// 여러 문법을 조합한 실용적인 함수
function createApiRequest({
    endpoint,
    method = "GET",
    headers = {},
    body = null,
    timeout = 5000
} = {}) {
    // Template Literals + Optional Chaining + Nullish Coalescing
    const url = endpoint ?? throw new Error("Endpoint is required");
    
    // Spread + Shorthand
    const config = {
        method,
        headers: {
            "Content-Type": "application/json",
            ...headers
        },
        ...(body && { body: JSON.stringify(body) }),
        timeout
    };
    
    // Ternary Operator + Template Literals
    return `
📡 API Request
--------------
URL: ${url}
Method: ${method}
Timeout: ${timeout}ms
Has Body: ${body ? "Yes" : "No"}
    `.trim();
}

// 사용
console.log(createApiRequest({
    endpoint: "/api/users",
    method: "POST",
    body: { name: "Alice" }
}));
profile
프론트엔드 입문 개발자입니다.

0개의 댓글