JavaScript/기초 문법과 자료형

JavaScript 연산자 완전 정리 - +, -, ==, ===, &&, || 마스터하기

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

연산자란?

연산자(Operator)는 하나 이상의 피연산자(operand)에 대해 특정 연산을 수행하는 기호입니다. JavaScript에는 다양한 종류의 연산자가 있으며, 각각 고유한 역할을 합니다.

🔍 연산자 분류

// 이항 연산자 (binary operator)
5 + 3;  // 피연산자 2개

// 단항 연산자 (unary operator)
-5;     // 피연산자 1개

// 삼항 연산자 (ternary operator)
condition ? value1 : value2;  // 피연산자 3개

산술 연산자

➕ 기본 산술 연산자

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

// 거듭제곱 (ES2016)
console.log(a ** b); // 1000

🔢 나머지 연산자 활용

// 짝수/홀수 판별
function isEven(number) {
    return number % 2 === 0;
}

console.log(isEven(4));  // true
console.log(isEven(5));  // false

// 배수 확인
function isMultipleOf3(number) {
    return number % 3 === 0;
}

console.log(isMultipleOf3(9));   // true
console.log(isMultipleOf3(10));  // false

// 순환 인덱스 만들기
function getCircularIndex(index, arrayLength) {
    return index % arrayLength;
}

let colors = ['red', 'green', 'blue'];
console.log(colors[getCircularIndex(5, colors.length)]); // 'green'

⚡ 거듭제곱 연산자의 활용

// 제곱 계산
console.log(2 ** 3);   // 8 (2의 3제곱)
console.log(5 ** 2);   // 25 (5의 2제곱)

// Math.pow()와 동일
console.log(Math.pow(2, 3)); // 8

// 제곱근 (0.5제곱)
console.log(9 ** 0.5);  // 3
console.log(16 ** 0.5); // 4

// 실무 예제: 면적 계산
function calculateCircleArea(radius) {
    return Math.PI * radius ** 2;
}

console.log(calculateCircleArea(5)); // 78.54...

할당 연산자

📝 기본 할당 연산자

let x = 10;  // 기본 할당

// 덧셈 할당
x += 5;      // x = x + 5
console.log(x); // 15

// 뺄셈 할당
x -= 3;      // x = x - 3
console.log(x); // 12

// 곱셈 할당
x *= 2;      // x = x * 2
console.log(x); // 24

// 나눗셈 할당
x /= 4;      // x = x / 4
console.log(x); // 6

// 나머지 할당
x %= 5;      // x = x % 5
console.log(x); // 1

// 거듭제곱 할당
x **= 3;     // x = x ** 3
console.log(x); // 1

🔄 체이닝 할당

// 체이닝 할당
let a, b, c;
a = b = c = 5;

console.log(a); // 5
console.log(b); // 5
console.log(c); // 5

// 주의: 객체의 경우
let obj1, obj2;
obj1 = obj2 = { value: 10 };

obj1.value = 20;
console.log(obj2.value); // 20 (같은 객체를 참조)

// 안전한 방법
obj1 = { value: 10 };
obj2 = { value: 10 };

💡 할당 연산자 실무 활용

// 카운터 증가
let clickCount = 0;
function handleClick() {
    clickCount += 1;
    console.log(`클릭 횟수: ${clickCount}`);
}

// 문자열 연결
let message = "안녕하세요";
message += ", 김철수님!";
console.log(message); // "안녕하세요, 김철수님!"

// 배열 요소 누적
let numbers = [1, 2, 3, 4, 5];
let sum = 0;
numbers.forEach(num => sum += num);
console.log(sum); // 15

// 객체 속성 업데이트
let user = { score: 100 };
user.score += 50;  // 점수 증가
console.log(user.score); // 150

비교 연산자

🔍 동등성 비교: == vs ===

가장 중요한 개념 중 하나입니다!

// == (느슨한 비교) - 타입 변환 후 비교
console.log(5 == "5");     // true
console.log(1 == true);    // true
console.log(0 == false);   // true
console.log(null == undefined); // true

// === (엄격한 비교) - 타입과 값 모두 비교
console.log(5 === "5");    // false
console.log(1 === true);   // false
console.log(0 === false);  // false
console.log(null === undefined); // false

⚠️ == 연산자의 함정

// 예상치 못한 결과들
console.log("" == 0);      // true
console.log("" == false);  // true
console.log("0" == false); // true
console.log(" \t\r\n" == 0); // true

// 배열과 문자열
console.log([1] == "1");   // true
console.log([1,2] == "1,2"); // true
console.log([] == "");     // true

// 객체 비교는 참조 비교
let obj1 = { a: 1 };
let obj2 = { a: 1 };
console.log(obj1 == obj2);  // false
console.log(obj1 === obj2); // false

✅ 권장사항: === 사용하기

// ❌ 피해야 할 패턴
if (userInput == 0) {
    // "0", false, "", [] 등도 모두 true가 됨
}

// ✅ 권장 패턴
if (userInput === 0) {
    // 정확히 숫자 0일 때만 true
}

// null/undefined 체크
function processValue(value) {
    // ❌ 잘못된 방법
    if (value == null) {
        // undefined도 걸림
    }

    // ✅ 정확한 방법
    if (value === null) {
        // 정확히 null일 때만
    }

    // ✅ null이나 undefined 둘 다 체크하려면
    if (value == null) {
        // 이 경우만 == 사용 고려
    }
}

📊 관계 비교 연산자

let a = 5;
let b = 3;

console.log(a > b);   // true  (초과)
console.log(a < b);   // false (미만)
console.log(a >= b);  // true  (이상)
console.log(a <= b);  // false (이하)

// 문자열 비교 (사전식 순서)
console.log("apple" < "banana");  // true
console.log("Apple" < "apple");   // true (대문자가 먼저)
console.log("10" < "9");          // true (문자열은 사전식)

// 날짜 비교
let date1 = new Date('2023-01-01');
let date2 = new Date('2023-12-31');
console.log(date1 < date2);  // true

🔍 비교 연산자 실무 예제

// 나이 그룹 분류
function getAgeGroup(age) {
    if (age < 13) return "어린이";
    if (age >= 13 && age < 20) return "청소년";
    if (age >= 20 && age < 65) return "성인";
    return "노인";
}

// 점수 등급 계산
function getGrade(score) {
    if (score >= 90) return 'A';
    if (score >= 80) return 'B';
    if (score >= 70) return 'C';
    if (score >= 60) return 'D';
    return 'F';
}

// 가격 비교 시스템
function comparePrices(price1, price2) {
    if (price1 === price2) {
        return "동일한 가격";
    } else if (price1 < price2) {
        return `첫 번째가 ${price2 - price1}원 저렴`;
    } else {
        return `두 번째가 ${price1 - price2}원 저렴`;
    }
}

console.log(comparePrices(15000, 12000)); 
// "두 번째가 3000원 저렴"

논리 연산자

🔗 기본 논리 연산자

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

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

// NOT (!) 연산자
console.log(!true);   // false
console.log(!false);  // true
console.log(!!true);  // true (이중 부정으로 불린 변환)

⚡ 단축 평가 (Short-Circuit Evaluation)

// && 단축 평가: 첫 번째가 falsy면 두 번째 실행 안 함
let user = null;
user && user.sayHello(); // user가 null이므로 sayHello() 실행 안 함

// || 단축 평가: 첫 번째가 truthy면 두 번째 실행 안 함
let name = userName || "기본 이름";
console.log(name); // userName이 없으면 "기본 이름" 사용

// 실무 활용
function greet(name) {
    name = name || "익명";
    console.log(`안녕하세요, ${name}님!`);
}

greet("김철수");  // "안녕하세요, 김철수님!"
greet();         // "안녕하세요, 익명님!"

🎯 논리 연산자 고급 활용

// 조건부 실행
let isLoggedIn = true;
let hasPermission = false;

// && 활용한 조건부 실행
isLoggedIn && hasPermission && showAdminPanel();

// || 활용한 기본값 설정
function processConfig(config) {
    const settings = {
        theme: config.theme || 'light',
        language: config.language || 'ko',
        timeout: config.timeout || 5000
    };
    return settings;
}

// Nullish Coalescing (??) - ES2020
let value = null;
let defaultValue = "기본값";

// || vs ??의 차이
console.log(value || defaultValue);    // "기본값"
console.log(value ?? defaultValue);    // "기본값"

let emptyString = "";
console.log(emptyString || "기본");    // "기본" (빈 문자열은 falsy)
console.log(emptyString ?? "기본");    // "" (null/undefined가 아니므로)

let zero = 0;
console.log(zero || 100);              // 100 (0은 falsy)
console.log(zero ?? 100);              // 0 (null/undefined가 아니므로)

🔄 논리 연산자 체이닝

// 복잡한 조건 체크
function canAccess(user) {
    return user && 
           user.isActive && 
           user.role && 
           (user.role === 'admin' || user.role === 'moderator') &&
           user.permissions &&
           user.permissions.includes('read');
}

// 기본값 설정 체이닝
function getDisplayName(user) {
    return user && user.profile && user.profile.displayName ||
           user && user.name ||
           user && user.email ||
           "익명 사용자";
}

// Optional Chaining (?.) - ES2020
function getDisplayNameSafe(user) {
    return user?.profile?.displayName ||
           user?.name ||
           user?.email ||
           "익명 사용자";
}

💡 논리 연산자 실무 패턴

// 권한 체크 시스템
class PermissionChecker {
    static canEdit(user, resource) {
        return user && 
               user.isActive && 
               resource &&
               (user.id === resource.ownerId || 
                user.role === 'admin' ||
                (user.role === 'editor' && resource.status === 'draft'));
    }

    static canDelete(user, resource) {
        return user &&
               user.isActive &&
               resource &&
               (user.id === resource.ownerId || user.role === 'admin');
    }
}

// 조건부 CSS 클래스 적용
function getElementClasses(element, state) {
    const classes = ['base-class'];

    state.isActive && classes.push('active');
    state.isHovered && classes.push('hovered');
    state.isDisabled && classes.push('disabled');

    return classes.join(' ');
}

// 에러 처리
function safeOperation(data, callback) {
    data && 
    typeof callback === 'function' && 
    callback(data);
}

증감 연산자

📈 전위와 후위 증감

let count = 5;

// 전위 증가 (++variable)
console.log(++count); // 6 (증가 후 값 반환)
console.log(count);   // 6

// 후위 증가 (variable++)
count = 5;
console.log(count++); // 5 (현재 값 반환 후 증가)
console.log(count);   // 6

// 전위 감소 (--variable)
count = 5;
console.log(--count); // 4 (감소 후 값 반환)
console.log(count);   // 4

// 후위 감소 (variable--)
count = 5;
console.log(count--); // 5 (현재 값 반환 후 감소)
console.log(count);   // 4

🔄 증감 연산자 활용

// 반복문에서의 활용
for (let i = 0; i < 5; i++) {
    console.log(i); // 0, 1, 2, 3, 4
}

for (let j = 5; j > 0; j--) {
    console.log(j); // 5, 4, 3, 2, 1
}

// 카운터 관리
class Counter {
    constructor(initialValue = 0) {
        this.value = initialValue;
    }

    increment() {
        return ++this.value; // 증가 후 값 반환
    }

    decrement() {
        return --this.value; // 감소 후 값 반환
    }

    postIncrement() {
        return this.value++; // 현재 값 반환 후 증가
    }

    getValue() {
        return this.value;
    }
}

const counter = new Counter(10);
console.log(counter.postIncrement()); // 10
console.log(counter.getValue());      // 11
console.log(counter.increment());     // 12

⚠️ 증감 연산자 주의점

// 복잡한 표현식에서의 주의점
let i = 1;
let result = i++ + ++i; // 1 + 3 = 4
console.log(result); // 4
console.log(i);      // 3

// 가독성을 위해 피해야 할 패턴
let arr = [1, 2, 3];
i = 0;
// ❌ 복잡하고 헷갈림
console.log(arr[i++] + arr[++i]);

// ✅ 명확하게 분리
i = 0;
console.log(arr[i] + arr[i + 2]);
i += 2;

문자열 연산자

🔤 문자열 연결

// + 연산자를 사용한 문자열 연결
let firstName = "김";
let lastName = "철수";
let fullName = firstName + lastName;
console.log(fullName); // "김철수"

// 문자열과 숫자 연결
let age = 25;
let message = "나이는 " + age + "세입니다.";
console.log(message); // "나이는 25세입니다."

// += 연산자 활용
let story = "옛날 옛적에";
story += " 한 마을에";
story += " 착한 농부가 살았습니다.";
console.log(story); // "옛날 옛적에 한 마을에 착한 농부가 살았습니다."

🚨 타입 강제 변환 주의점

// 문자열과 숫자의 혼용
console.log("5" + 3);     // "53" (문자열 연결)
console.log("5" - 3);     // 2 (숫자 변환 후 연산)
console.log("5" * 3);     // 15 (숫자 변환 후 연산)
console.log("5" / 3);     // 1.666... (숫자 변환 후 연산)

// 예상치 못한 결과
console.log(1 + 2 + "3"); // "33" (앞에서부터 계산)
console.log("1" + 2 + 3); // "123" (문자열로 연결)

// 안전한 문자열 연결
function safeConcat(a, b) {
    return String(a) + String(b);
}

// 템플릿 리터럴 사용 권장
let name = "김철수";
let age = 25;
let info = `이름: ${name}, 나이: ${age}`;
console.log(info); // "이름: 김철수, 나이: 25"

💡 문자열 연산자 실무 활용

// 동적 CSS 클래스 생성
function buildCssClass(base, modifiers = []) {
    let className = base;
    modifiers.forEach(modifier => {
        className += " " + base + "--" + modifier;
    });
    return className;
}

console.log(buildCssClass("button", ["primary", "large"]));
// "button button--primary button--large"

// URL 구성
function buildApiUrl(baseUrl, endpoint, queryParams = {}) {
    let url = baseUrl + "/" + endpoint;

    const params = Object.entries(queryParams)
        .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
        .join("&");

    if (params) {
        url += "?" + params;
    }

    return url;
}

const url = buildApiUrl("https://api.example.com", "users", {
    page: 1,
    limit: 10,
    search: "김철수"
});
console.log(url);
// "https://api.example.com/users?page=1&limit=10&search=%EA%B9%80%EC%B2%A0%EC%88%98"

// HTML 문자열 생성
function createHTML(tag, content, attributes = {}) {
    let html = `<${tag}`;

    Object.entries(attributes).forEach(([key, value]) => {
        html += ` ${key}="${value}"`;
    });

    html += `>${content}</${tag}>`;
    return html;
}

const linkHTML = createHTML("a", "클릭하세요", {
    href: "https://example.com",
    class: "btn btn-primary",
    target: "_blank"
});
console.log(linkHTML);
// <a href="https://example.com" class="btn btn-primary" target="_blank">클릭하세요</a>

조건(삼항) 연산자

❓ 기본 문법

// 기본 형태: condition ? value1 : value2
let age = 18;
let message = age >= 18 ? "성인" : "미성년자";
console.log(message); // "성인"

// if-else와 비교
// if-else 방식
let status;
if (age >= 18) {
    status = "성인";
} else {
    status = "미성년자";
}

// 삼항 연산자 방식
let status2 = age >= 18 ? "성인" : "미성년자";

🔄 중첩 삼항 연산자

// 여러 조건 처리
let score = 85;
let grade = score >= 90 ? "A" : 
            score >= 80 ? "B" : 
            score >= 70 ? "C" : 
            score >= 60 ? "D" : "F";
console.log(grade); // "B"

// 가독성 향상을 위한 개행
let weatherMessage = temperature > 30 ? "매우 더움" :
                    temperature > 20 ? "따뜻함" :
                    temperature > 10 ? "서늘함" :
                    temperature > 0  ? "추움" :
                                      "매우 추움";

💡 삼항 연산자 활용 패턴

// 기본값 설정
function greet(name) {
    const displayName = name ? name : "익명";
    return `안녕하세요, ${displayName}님!`;
}

// 조건부 속성 할당
const button = {
    text: "클릭",
    className: isActive ? "active" : "inactive",
    disabled: isLoading ? true : false
};

// 조건부 함수 호출
const result = hasPermission ? processData(data) : null;

// React JSX에서의 조건부 렌더링 패턴
// {user ? <UserProfile user={user} /> : <LoginButton />}

// API 응답 처리
function handleApiResponse(response) {
    return response.ok 
        ? response.data 
        : { error: response.message || "알 수 없는 오류" };
}

// 배열 필터링에서의 활용
const adults = people.filter(person => person.age >= 18 ? true : false);

⚠️ 삼항 연산자 주의점

// ❌ 너무 복잡한 중첩은 피하기
let complex = a > b ? c > d ? e > f ? 1 : 2 : 3 : 4; // 가독성 나쁨

// ✅ 함수로 분리하기
function getComplexValue(a, b, c, d, e, f) {
    if (a > b) {
        if (c > d) {
            return e > f ? 1 : 2;
        }
        return 3;
    }
    return 4;
}

// ❌ 부작용이 있는 표현식 사용 주의
let counter = 0;
let result = condition ? counter++ : counter--; // 부작용 있음

// ✅ 명확한 분리
if (condition) {
    counter++;
    result = counter;
} else {
    counter--;
    result = counter;
}

기타 유용한 연산자

🔍 typeof 연산자

// 타입 확인
console.log(typeof "Hello");    // "string"
console.log(typeof 42);         // "number"
console.log(typeof true);       // "boolean"
console.log(typeof undefined);  // "undefined"
console.log(typeof null);       // "object" (JavaScript의 유명한 버그)
console.log(typeof {});         // "object"
console.log(typeof []);         // "object"
console.log(typeof function(){}); // "function"

🔗 in 연산자

// 객체 속성 존재 확인
let person = { name: "김철수", age: 30 };
console.log("name" in person);     // true
console.log("address" in person);  // false

// 배열 인덱스 확인
let arr = [1, 2, 3];
console.log(0 in arr);    // true
console.log(3 in arr);    // false
console.log("length" in arr); // true

// 프로토타입 체인 확인
console.log("toString" in person); // true (Object.prototype에서 상속)

🏭 instanceof 연산자

// 생성자 함수와 클래스 확인
let date = new Date();
console.log(date instanceof Date);   // true
console.log(date instanceof Object); // true

let arr = [1, 2, 3];
console.log(arr instanceof Array);  // true
console.log(arr instanceof Object); // true

// 사용자 정의 클래스
class Person {
    constructor(name) {
        this.name = name;
    }
}

let person = new Person("김철수");
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true

🔄 스프레드 연산자 (...)

// 배열 스프레드
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

// 객체 스프레드
let obj1 = { a: 1, b: 2 };
let obj2 = { c: 3, d: 4 };
let merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }

// 함수 인수 스프레드
function sum(a, b, c) {
    return a + b + c;
}
let numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6

🎯 구조 분해 할당과 연산자

// 배열 구조 분해
let [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]

// 객체 구조 분해
let { name, age, ...others } = { 
    name: "김철수", 
    age: 30, 
    city: "서울", 
    country: "한국" 
};
console.log(name); // "김철수"
console.log(others); // { city: "서울", country: "한국" }

// 기본값과 함께
let { x = 10, y = 20 } = { x: 5 };
console.log(x); // 5
console.log(y); // 20

연산자 우선순위

📊 우선순위 표

// 1. 괄호 ()
console.log(2 + 3 * 4);     // 14 (곱셈 먼저)
console.log((2 + 3) * 4);   // 20 (괄호 먼저)

// 2. 단항 연산자 (!, -, +, ++, --)
let x = 5;
console.log(-x * 2);        // -10

// 3. 산술 연산자 (**, *, /, %, +, -)
console.log(2 ** 3 * 4);    // 32 (2^3 = 8, 8 * 4 = 32)

// 4. 비교 연산자 (<, >, <=, >=)
console.log(3 + 4 > 2 * 3); // true (7 > 6)

// 5. 동등성 연산자 (==, !=, ===, !==)
console.log(1 + 1 == 2);    // true

// 6. 논리 연산자 (&&, ||)
console.log(true || false && false); // true (&& 우선)
console.log((true || false) && false); // false

🔄 실무에서의 우선순위 활용

// 복잡한 조건식
function canAccess(user, resource) {
    // 우선순위: ! > && > ||
    return user.isActive && 
           !user.isBanned && 
           (user.role === 'admin' || 
            user.id === resource.ownerId ||
            user.permissions.includes(resource.type));
}

// 계산식의 명확한 작성
function calculateTotalPrice(price, quantity, discountRate, taxRate) {
    // 괄호로 의도 명확히 하기
    return (price * quantity * (1 - discountRate)) * (1 + taxRate);
}

// 조건부 실행의 우선순위
let score = 85;
// ❌ 헷갈릴 수 있는 코드
let result = score > 90 && "A" || score > 80 && "B" || "C";

// ✅ 명확한 코드
let result2 = score > 90 ? "A" : 
              score > 80 ? "B" : "C";

실무 활용 패턴

🔧 방어적 프로그래밍

// null/undefined 안전한 접근
function getNestedValue(obj, path, defaultValue = null) {
    const keys = path.split('.');
    let current = obj;

    for (let key of keys) {
        if (current == null || typeof current !== 'object') {
            return defaultValue;
        }
        current = current[key];
    }

    return current !== undefined ? current : defaultValue;
}

// 사용 예
const user = {
    profile: {
        settings: {
            theme: 'dark'
        }
    }
};

console.log(getNestedValue(user, 'profile.settings.theme')); // 'dark'
console.log(getNestedValue(user, 'profile.settings.language', 'ko')); // 'ko'

🎯 조건부 실행 패턴

// 조건부 메서드 호출
class Logger {
    static log(message, condition = true) {
        condition && console.log(`[LOG] ${message}`);
    }

    static error(message, condition = true) {
        condition && console.error(`[ERROR] ${message}`);
    }
}

// 디버그 모드에서만 로그
const DEBUG_MODE = true;
Logger.log("디버그 정보", DEBUG_MODE);

// 권한 체크 후 실행
function performAdminAction(user, action) {
    user.role === 'admin' && typeof action === 'function' && action();
}

🔗 연산자 체이닝 패턴

// 유효성 검사 체이닝
class Validator {
    constructor(value) {
        this.value = value;
        this.valid = true;
        this.errors = [];
    }

    required(message = "필수 입력 항목입니다") {
        if (this.value == null || this.value === '') {
            this.valid = false;
            this.errors.push(message);
        }
        return this;
    }

    minLength(length, message = `최소 ${length}자 이상 입력해주세요`) {
        if (this.valid && this.value.length < length) {
            this.valid = false;
            this.errors.push(message);
        }
        return this;
    }

    email(message = "올바른 이메일 형식이 아닙니다") {
        if (this.valid && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.value)) {
            this.valid = false;
            this.errors.push(message);
        }
        return this;
    }

    getResult() {
        return {
            valid: this.valid,
            errors: this.errors
        };
    }
}

// 사용 예
const emailValidation = new Validator("user@example.com")
    .required()
    .email()
    .getResult();

console.log(emailValidation); // { valid: true, errors: [] }

💡 성능 최적화 패턴

// 지연 계산 (Lazy evaluation)
const expensiveCalculation = () => {
    console.log("비싼 계산 실행됨");
    return 1000000;
};

// 조건이 false면 뒤 함수 실행 안 됨
const result = false && expensiveCalculation(); // "비싼 계산 실행됨" 출력 안 됨

// 메모이제이션 패턴
const memoize = (fn) => {
    const cache = new Map();
    return (...args) => {
        const key = JSON.stringify(args);

        // 캐시에 있으면 반환, 없으면 계산 후 저장
        return cache.has(key) 
            ? cache.get(key)
            : (cache.set(key, fn(...args)), cache.get(key));
    };
};

const fibonacci = memoize((n) => {
    return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
});

🎨 함수형 프로그래밍 패턴

// 함수 합성을 위한 연산자 활용
const pipe = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);

const addTen = x => x + 10;
const multiplyByTwo = x => x * 2;
const subtractFive = x => x - 5;

const process = pipe(addTen, multiplyByTwo, subtractFive);
console.log(process(5)); // ((5 + 10) * 2) - 5 = 25

// 조건부 변환
const conditionalMap = (condition, transformFn) => value => 
    condition(value) ? transformFn(value) : value;

const numbers = [1, 2, 3, 4, 5];
const doubleEvens = numbers.map(conditionalMap(n => n % 2 === 0, n => n * 2));
console.log(doubleEvens); // [1, 4, 3, 8, 5]

마무리

JavaScript 연산자는 프로그래밍의 기본 구성 요소입니다. 특히 =====의 차이, 논리 연산자의 단축 평가, 연산자 우선순위를 정확히 이해하는 것이 중요합니다.

✅ 핵심 정리

  1. 비교 연산자: ===를 기본으로 사용하고, ==는 신중하게
  2. 논리 연산자: 단축 평가를 활용한 효율적인 코드 작성
  3. 우선순위: 괄호를 활용해 의도를 명확하게 표현
  4. 타입 변환: 의도하지 않은 변환 주의

🚀 실무 권장사항

  1. 의도 명확하게: 괄호와 명시적 변환 사용
  2. 안전한 코드: null/undefined 체크 철저히
  3. 가독성 우선: 복잡한 연산자 체이닝보다 명확한 분리
  4. 성능 고려: 단축 평가 활용으로 불필요한 연산 방지

연산자를 정확히 이해하고 활용하면 더 안전하고 효율적인 JavaScript 코드를 작성할 수 있습니다. 실제 프로젝트에서 다양한 연산자를 사용해보며 경험을 쌓아가세요!

연산자에 대한 설명이 도움이 되셨나요? 더 궁금한 연산자나 실무 활용 팁이 있다면 댓글로 남겨주세요! 💬