자바스크립트 연산자 완전 정복: 코드와 함께 쉽고 빠르게!
안녕하세요! 오늘은 자바스크립트 프로그래밍의 핵심 요소인 연산자에 대해 자세히 알아보겠습니다. 연산자는 마치 도구 상자와 같아서, 이 도구들을 잘 활용하면 데이터를 자유자재로 조작하고, 복잡한 로직을 구현하며, 프로그램을 더욱 강력하게 만들 수 있습니다.
자바스크립트의 연산자는 그 종류가 매우 다양하지만, 크게 몇 가지 범주로 나누어 살펴볼 수 있습니다. 각 연산자의 역할과 사용법을 예제 코드와 함께 쉽고 명확하게 설명해 드릴게요! 코드를 직접 따라 쳐보면서 익히시면 이해가 훨씬 빠를 거예요!
1. 할당 연산자 (Assignment Operators)
할당 연산자는 변수에 값을 부여할 때 사용됩니다. 단순한 값 할당부터 복합적인 연산과 할당을 동시에 수행하는 복합 할당 연산자까지 다양합니다. 이 연산자들은 코드를 더 간결하고 효율적으로 만들어줍니다.
=
(할당): 가장 기본적인 연산자로, 오른쪽 피연산자의 값을 왼쪽 피연산자에 할당합니다.let myNumber = 10; // 변수 myNumber에 숫자 10을 할당 let myString = "Hello"; // 변수 myString에 문자열 "Hello"를 할당
+=
(덧셈 할당): 왼쪽 피연산자에 오른쪽 피연산자를 더하고 결과를 다시 왼쪽 피연산자에 할당합니다. 숫자의 덧셈뿐만 아니라 문자열 연결에도 사용될 수 있습니다.let count = 5; count += 3; // count는 8 (count = count + 3과 같음) let greeting = "안녕"; greeting += "하세요!"; // greeting은 "안녕하세요!"
-=
(뺄셈 할당): 왼쪽 피연산자에서 오른쪽 피연산자를 뺀 후 결과를 왼쪽 피연산자에 할당합니다.let total = 100; total -= 20; // total은 80 (total = total - 20과 같음)
*=
(곱셈 할당): 왼쪽 피연산자에 오른쪽 피연산자를 곱한 후 결과를 왼쪽 피연산자에 할당합니다.let price = 5000; price *= 2; // price는 10000 (price = price * 2와 같음)
/=
(나눗셈 할당): 왼쪽 피연산자를 오른쪽 피연산자로 나눈 후 결과를 왼쪽 피연산자에 할당합니다.let amount = 200; amount /= 4; // amount는 50 (amount = amount / 4와 같음)
%=
(나머지 할당): 왼쪽 피연산자를 오른쪽 피연산자로 나눈 나머지를 왼쪽 피연산자에 할당합니다. 주로 어떤 수가 짝수/홀수인지 판별하거나, 주기적인 계산을 할 때 유용합니다.let remainder = 17; remainder %= 5; // remainder는 2 (17을 5로 나눈 나머지)
**=
(거듭제곱 할당): 왼쪽 피연산자를 오른쪽 피연산자의 거듭제곱으로 계산한 후 결과를 왼쪽 피연산자에 할당합니다. (ES2016부터 사용 가능)let base = 3; base **= 2; // base는 9 (base = base ** 2, 즉 3의 2제곱과 같음)
&&=
(논리 AND 할당): 왼쪽 피연산자가true
(또는 truthy 값)일 경우에만 오른쪽 피연산자의 값을 왼쪽 피연산자에 할당합니다. 이는 변수에 기본값을 설정하는 유용한 방법이 될 수 있습니다. (ES2020부터 사용 가능)let config = { value: 10 }; config.value &&= 20; // config.value는 20 (config.value가 truthy이므로 20이 할당됨) let settings = { value: 0 }; // 0은 falsy 값 settings.value &&= 100; // settings.value는 0 (settings.value가 falsy이므로 할당되지 않음)
||=
(논리 OR 할당): 왼쪽 피연산자가false
(또는 falsy 값)일 경우에만 오른쪽 피연산자의 값을 왼쪽 피연산자에 할당합니다. 이는 변수에 기본값을 설정하는 데 매우 자주 사용됩니다. (ES2020부터 사용 가능)let userPreference = null; userPreference ||= "dark"; // userPreference는 "dark" (null은 falsy이므로 할당됨) let userName = "Alice"; userName ||= "Guest"; // userName은 "Alice" (userName이 truthy이므로 할당되지 않음)
??=
(Nullish Coalescing 할당): 왼쪽 피연산자가null
또는undefined
일 경우에만 오른쪽 피연산자의 값을 왼쪽 피연산자에 할당합니다.||=
와 유사하지만,0
이나""
(빈 문자열) 같은 falsy 값은 무시하지 않고 유효한 값으로 취급합니다. (ES2020부터 사용 가능)let userSetting = null; userSetting ??= "default"; // userSetting은 "default" let countValue = 0; countValue ??= 10; // countValue는 0 (0은 null 또는 undefined가 아니므로 할당되지 않음) let emptyString = ""; emptyString ??= "fallback"; // emptyString은 "" (빈 문자열은 null 또는 undefined가 아님)
2. 비교 연산자 (Comparison Operators)
두 피연산자를 비교하여 그 결과가 참인지 거짓인지를 나타내는 불리언(boolean) 값 (true
또는 false
)을 반환합니다. 조건문, 반복문 등 프로그램의 흐름을 제어하는 데 필수적입니다.
==
(동등): 값이 같은지 비교합니다. 이때 자바스크립트는 필요에 따라 타입 변환(Type Coercion)을 시도할 수 있습니다. 예를 들어, 숫자와 문자열을 비교할 때 문자열을 숫자로 변환하여 비교합니다.10 == "10" // true (문자열 "10"이 숫자 10으로 변환되어 비교됨) 0 == false // true (false가 0으로 변환되어 비교됨) null == undefined // true
!=
(부등): 값이 다른지 비교합니다.==
와 마찬가지로 타입 변환이 일어날 수 있습니다.10 != "10" // false (값이 같다고 판단됨)
===
(일치): 값과 타입이 모두 같은지 엄격하게 비교합니다. 이 연산자는 타입 변환을 수행하지 않으므로, 예상치 못한 타입 변환으로 인한 오류를 방지할 수 있어 일반적으로==
보다 선호됩니다.10 === "10" // false (값은 같지만, 타입이 다름: number vs string) 0 === false // false (값과 타입 모두 다름) null === undefined // false
!==
(불일치): 값 또는 타입이 다른지 엄격하게 비교합니다.===
의 반대입니다.10 !== "10" // true (타입이 다르므로 불일치)
>
(보다 큼): 왼쪽 피연산자가 오른쪽 피연산자보다 큰지 비교합니다.10 > 5 // true
<
(보다 작음): 왼쪽 피연산자가 오른쪽 피연산자보다 작은지 비교합니다.10 < 5 // false
>=
(크거나 같음): 왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같은지 비교합니다.10 >= 10 // true
<=
(작거나 같음): 왼쪽 피연산자가 오른쪽 피연산자보다 작거나 같은지 비교합니다.10 <= 5 // false
3. 산술 연산자 (Arithmetic Operators)
숫자 값을 계산하는 데 사용되는 기본적인 수학 연산자입니다.
+
(덧셈): 두 숫자를 더합니다. 피연산자 중 하나라도 문자열이면 문자열 연결 연산자로 작동합니다.10 + 5 // 15 "Hello" + " World" // "Hello World" (문자열 연결) "값: " + 10 // "값: 10" (숫자가 문자열로 변환되어 연결)
-
(뺄셈): 한 숫자에서 다른 숫자를 뺍니다.10 - 5 // 5
*
(곱셈): 두 숫자를 곱합니다.10 * 5 // 50
/
(나눗셈): 한 숫자를 다른 숫자로 나눕니다. 0으로 나누면Infinity
또는NaN
(Not a Number)이 반환될 수 있습니다.10 / 5 // 2 10 / 0 // Infinity 0 / 0 // NaN
%
(나머지): 한 숫자를 다른 숫자로 나눈 나머지를 반환합니다.10 % 3 // 1 (10을 3으로 나누면 몫 3, 나머지 1)
**
(거듭제곱): 첫 번째 피연산자를 두 번째 피연산자의 거듭제곱으로 계산합니다. (ES2016부터 사용 가능)2 ** 3 // 8 (2 * 2 * 2)
++
(증가): 피연산자의 값을 1 증가시킵니다. 변수의 앞에 오느냐 뒤에 오느냐에 따라 동작 방식이 달라집니다.- 전위 (Prefix):
++x
와 같이 변수 앞에 오면, 값을 먼저 1 증가시킨 후 그 값을 사용합니다.let x = 5; let y = ++x; // x는 6이 되고, y도 6이 됩니다.
- 후위 (Postfix):
x++
와 같이 변수 뒤에 오면, 현재 값을 먼저 사용한 후 값을 1 증가시킵니다.let x = 5; let y = x++; // y는 5가 되고, 그 후에 x는 6이 됩니다.
- 전위 (Prefix):
--
(감소): 피연산자의 값을 1 감소시킵니다.++
와 마찬가지로 전위/후위에 따라 동작이 다릅니다.- 전위 (Prefix):
--x
와 같이 변수 앞에 오면, 값을 먼저 1 감소시킨 후 그 값을 사용합니다.let x = 5; let y = --x; // x는 4가 되고, y도 4가 됩니다.
- 후위 (Postfix):
x--
와 같이 변수 뒤에 오면, 현재 값을 먼저 사용한 후 값을 1 감소시킵니다.let x = 5; let y = x--; // y는 5가 되고, 그 후에 x는 4가 됩니다.
- 전위 (Prefix):
+
(단항 덧셈): 피연산자를 숫자로 변환하려고 시도합니다. 주로 문자열이나 불리언 값을 숫자로 명시적으로 변환할 때 사용됩니다.+"10" // 10 (문자열 "10"이 숫자 10으로 변환됨) +true // 1 +false // 0 +"hello" // NaN
-
(단항 뺄셈): 피연산자를 음수로 만듭니다. 숫자 값을 음수로 바꾸거나, 문자열로 된 숫자를 숫자로 변환한 후 음수로 만듭니다.-10 // -10 -"5" // -5 (문자열 "5"가 숫자 5로 변환 후 -5) -"abc" // NaN
4. 논리 연산자 (Logical Operators)
불리언(boolean) 값을 다루며, 여러 조건식을 결합하거나 논리적인 판단을 내릴 때 사용됩니다. 중요한 특징은 단락 평가(short-circuit evaluation)를 수행한다는 것입니다.
&&
(논리 AND): 양쪽 피연산자가 모두true
(또는 truthy)일 때true
를 반환합니다. 만약 왼쪽 피연산자가false
(또는 falsy)이면, 오른쪽 피연산자를 평가하지 않고 바로 왼쪽 피연산자의 값을 반환합니다. 이를 단락 평가라고 합니다.true && true // true true && false // false false && true // false (왼쪽이 false이므로 오른쪽 평가 안 함) let value = 10; let result = (value > 5) && "조건 만족"; // result는 "조건 만족" let result2 = (value < 5) && "조건 만족"; // result2는 false
||
(논리 OR): 한쪽 피연산자라도true
(또는 truthy)일 때true
를 반환합니다. 만약 왼쪽 피연산자가true
(또는 truthy)이면, 오른쪽 피연산자를 평가하지 않고 바로 왼쪽 피연산자의 값을 반환합니다. 이 역시 단락 평가입니다.true || false // true (왼쪽이 true이므로 오른쪽 평가 안 함) false || false // false false || true // true let userName = ""; let displayName = userName || "Guest"; // displayName은 "Guest" (빈 문자열은 falsy이므로 "Guest"가 할당됨) let userAge = 25; let displayAge = userAge || 18; // displayAge는 25 (25는 truthy이므로 18이 할당되지 않음)
!
(논리 NOT): 피연산자의 논리 값을 반전시킵니다 (true
는false
로,false
는true
로). 단일 피연산자에 사용됩니다.!true // false !false // true !"Hello" // false (truthy 값의 반대) !0 // true (falsy 값의 반대) !null // true !undefined // true
??
(Nullish Coalescing 연산자): 왼쪽 피연산자가null
또는undefined
일 때만 오른쪽 피연산자를 반환하고, 그 외의 경우에는 왼쪽 피연산자를 반환합니다.||
와 유사하지만,0
이나""
(빈 문자열) 같은 falsy 값은 유효한 값으로 취급하여 무시하지 않는다는 점이 다릅니다. (ES2020부터 사용 가능)const name = null; const defaultName = "Guest"; const displayName = name ?? defaultName; // displayName은 "Guest" const temperature = 0; // 0은 falsy이지만 nullish는 아님 const displayTemp = temperature ?? 25; // displayTemp는 0 const userEmail = ""; // 빈 문자열은 falsy이지만 nullish는 아님 const fallbackEmail = userEmail ?? "no_email@example.com"; // fallbackEmail은 ""
이 연산자는 특히 API 응답 등에서 값이 명시적으로
null
또는undefined
일 때만 기본값을 사용하고 싶을 때 유용합니다.
5. 비트 연산자 (Bitwise Operators)
비트 연산자는 피연산자를 32비트 정수로 변환하여 이진수(비트) 단위로 연산을 수행합니다. 주로 저수준 프로그래밍, 권한 설정, 플래그 관리 또는 특정 알고리즘에서 효율적인 계산을 위해 사용됩니다. 일반적인 웹 개발에서는 자주 사용되지 않을 수 있지만, 알아두면 좋습니다.
&
(비트 AND): 두 피연산자의 해당 비트가 모두1
일 때만 결과 비트를1
로 설정합니다.5 & 3 // 1 (이진수: 0101 & 0011 -> 0001)
|
(비트 OR): 두 피연산자의 해당 비트 중 하나라도1
일 때 결과 비트를1
로 설정합니다.5 | 3 // 7 (이진수: 0101 | 0011 -> 0111)
^
(비트 XOR): 두 피연산자의 해당 비트가 서로 다를 때만 결과 비트를1
로 설정합니다.5 ^ 3 // 6 (이진수: 0101 ^ 0011 -> 0110)
~
(비트 NOT): 피연산자의 모든 비트를 반전시킵니다 (1의 보수). 즉, 0은 1로, 1은 0으로 바꿉니다. 결과는-(N+1)
과 같습니다.~5 // -6 (이진수: ~0000...0101 -> 1111...1010, 이는 2의 보수 표현에서 -6)
<<
(왼쪽 시프트): 피연산자의 비트를 왼쪽으로 지정된 비트 수만큼 이동시킵니다. 오른쪽에0
이 채워집니다. 이는N * (2 ** shiftCount)
와 동일한 효과를 냅니다.5 << 1 // 10 (이진수: 0101 -> 1010) 5 << 2 // 20 (이진수: 0101 -> 10100)
>>
(오른쪽 시프트): 피연산자의 비트를 오른쪽으로 지정된 비트 수만큼 이동시킵니다. 왼쪽에는 부호 비트가 채워집니다 (최상위 비트가 0이면 0, 1이면 1이 채워집니다).5 >> 1 // 2 (이진수: 0101 -> 0010) -5 >> 1 // -3 (이진수: ...11111011 -> ...11111101)
>>>
(부호 없는 오른쪽 시프트): 피연산자의 비트를 오른쪽으로 지정된 비트 수만큼 이동시킵니다. 왼쪽에는 항상0
이 채워집니다. 이로 인해 음수가 양수로 변환될 수 있습니다.5 >>> 1 // 2 (이진수: 0101 -> 0010) -5 >>> 1 // 2147483645 (음수가 양수로 변환됨, 32비트 정수의 최대 절반에 가까운 값)
6. 삼항(조건) 연산자 (Conditional (Ternary) Operator)
자바스크립트에서 유일하게 피연산자가 세 개인 연산자입니다. 간단한 조건에 따라 두 값 중 하나를 선택하여 반환할 때 사용되며, if-else
문의 간결한 대안이 될 수 있습니다.
조건 ? 값1 : 값2
:조건
이true
이면값1
을 반환하고,false
이면값2
를 반환합니다.let age = 20; let status = (age >= 18) ? "성인" : "미성년자"; // age가 18 이상이므로 status는 "성인" let isSunny = true; let activity = isSunny ? "야외 활동" : "실내 활동"; // isSunny가 true이므로 activity는 "야외 활동"
조건문이 매우 짧고 단순히 값만 할당하는 경우에 코드 가독성을 높이는 데 유용합니다.
7. 문자열 연산자 (String Operator)
문자열을 다루는 데 사용되며, 주로 문자열을 서로 연결하는 역할을 합니다.
+
(문자열 연결): 두 문자열을 합쳐서 새로운 문자열을 만듭니다. 피연산자 중 하나라도 문자열이면 나머지 피연산자도 문자열로 자동 변환되어 연결됩니다."Hello" + " World" // "Hello World" "결과: " + 10 // "결과: 10" (숫자 10이 문자열 "10"으로 변환되어 연결됨)
+=
(문자열 연결 할당): 왼쪽 피연산자 문자열에 오른쪽 피연산자 문자열을 연결한 후 결과를 다시 왼쪽 피연산자에 할당합니다.let message = "안녕"; message += "하세요"; // message는 "안녕하세요" message += "!"; // message는 "안녕하세요!"
8. 타입 연산자 (Type Operators)
변수의 데이터 타입을 확인하거나 새로운 객체 인스턴스를 생성하는 데 사용되는 연산자입니다.
typeof
: 피연산자의 데이터 타입을 나타내는 문자열을 반환합니다. 디버깅이나 조건부 로직에서 변수의 타입을 확인해야 할 때 유용합니다.typeof 10 // "number" typeof "hello" // "string" typeof true // "boolean" typeof undefined // "undefined" typeof null // "object" (❗주의: 자바스크립트의 역사적인 오류로, null은 실제로는 원시 타입이지만 typeof는 "object"를 반환합니다.) typeof {} // "object" typeof [] // "object" typeof function(){} // "function"
instanceof
: 어떤 객체가 특정 생성자 함수(클래스)의 인스턴스인지 여부를 확인하여true
또는false
를 반환합니다. 주로 객체 지향 프로그래밍에서 타입 검사를 할 때 사용됩니다.let arr = [1, 2, 3]; arr instanceof Array // true (arr는 Array의 인스턴스) let date = new Date(); date instanceof Date // true (date는 Date의 인스턴스) let customObject = {}; customObject instanceof Object // true (모든 객체는 Object의 인스턴스)
9. 기타 유용한 연산자 (Miscellaneous Operators)
위에 분류하기 어려운 다양한 목적의 연산자들이 있습니다. 이들도 자바스크립트 코드 작성에 중요한 역할을 합니다.
,
(쉼표 연산자): 여러 표현식을 한 줄에 나열할 수 있게 하며, 가장 마지막 표현식의 값을 반환합니다. 주로for
루프에서 여러 변수를 선언하거나 업데이트할 때 사용될 수 있습니다.let x = (10, 20, 30); // x는 30 (마지막 값인 30이 할당됨) for (let i = 0, j = 10; i <= 10; i++, j--) { // 루프 내에서 i는 증가하고 j는 감소 }
delete
: 객체의 속성이나 배열의 요소를 삭제합니다. 배열의 경우 삭제된 자리는undefined
가 되지만, 배열의length
속성은 변하지 않습니다.let user = { name: "Alice", age: 30 }; delete user.age; // user는 { name: "Alice" } console.log(user.age); // undefined let fruits = ["apple", "banana", "cherry"]; delete fruits[1]; // fruits는 ["apple", undefined, "cherry"] console.log(fruits.length); // 3 (길이는 그대로 유지)
in
: 특정 속성이 객체 또는 프로토타입 체인에 존재하는지 확인합니다.let person = { name: "John", age: 25 }; "name" in person // true "gender" in person // false let colors = ["red", "green"]; 0 in colors // true (인덱스도 속성으로 간주) "length" in colors // true (배열의 length 속성)
void
: 표현식을 평가하고 항상undefined
를 반환합니다. 주로 HTML<a>
태그의href
속성에서 링크 클릭 시 페이지 이동을 막고 스크립트를 실행할 때 사용됩니다.void(0); // undefined void("Hello World"); // undefined // HTML 예시: // <a href="javascript:void(0);">클릭해도 이동 안 함</a>
new
: 생성자 함수(또는 클래스)를 호출하여 새로운 객체 인스턴스를 생성합니다.this
키워드와 함께 객체 지향 프로그래밍의 핵심 요소입니다.let currentDate = new Date(); // 새로운 Date 객체 생성 (현재 날짜와 시간)
...
(스프레드 문법 / 나머지 매개변수):- 스프레드 문법 (Spread Syntax): 배열이나 객체의 요소를 개별적으로 펼쳐 새로운 배열/객체를 만들거나 함수 인자로 전달할 때 사용됩니다.
let arr1 = [1, 2]; let arr2 = [...arr1, 3, 4]; // arr2는 [1, 2, 3, 4] (arr1의 요소들이 펼쳐져 새로운 배열 생성) let obj1 = { a: 1, b: 2 }; let obj2 = { ...obj1, c: 3 }; // obj2는 { a: 1, b: 2, c: 3 } (obj1의 속성들이 복사되어 새로운 객체 생성) function add(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; add(...numbers); // 6 (배열 요소들이 개별 인자로 펼쳐져 전달됨)
- 나머지 매개변수 (Rest Parameters): 함수의 정의에서 사용되며, 전달된 인자들을 배열로 묶는 데 사용됩니다. 함수가 가변적인 수의 인자를 받을 때 유용합니다.
function sum(...numbers) { // numbers는 배열 return numbers.reduce((acc, current) => acc + current, 0); } sum(1, 2, 3); // 6 sum(1, 2, 3, 4, 5); // 15
- 스프레드 문법 (Spread Syntax): 배열이나 객체의 요소를 개별적으로 펼쳐 새로운 배열/객체를 만들거나 함수 인자로 전달할 때 사용됩니다.
()
(그룹화 연산자): 연산의 우선순위를 명확히 하기 위해 사용됩니다. 괄호 안의 연산이 다른 연산보다 먼저 수행됩니다.(10 + 5) * 2 // 30 (괄호 안의 덧셈이 먼저 수행됨) 10 + (5 * 2) // 20 (괄호 안의 곱셈이 먼저 수행됨)
[]
(멤버 접근 연산자 - 대괄호 표기법): 객체의 속성에 동적으로 접근하거나 배열의 요소에 접근할 때 사용됩니다. 속성 이름이 변수이거나 특수 문자를 포함할 때 유용합니다.let userProfile = { name: "John Doe", "last name": "Doe" }; userProfile["name"]; // "John Doe" userProfile["last name"];// "Doe" (공백이 있는 속성 접근) let scores = [90, 85, 92]; scores[0]; // 90
.
(멤버 접근 연산자 - 점 표기법): 객체의 속성에 접근할 때 사용되는 가장 일반적인 방법입니다. 속성 이름이 유효한 식별자일 때 사용합니다.let car = { brand: "Hyundai", model: "Sonata" }; car.brand; // "Hyundai" car.model; // "Sonata"
?.
(옵셔널 체이닝 연산자): 속성에 접근하기 전에 해당 속성이null
또는undefined
인지 확인합니다. 만약 중간 단계의 속성이null
또는undefined
이면, 에러 대신undefined
를 반환합니다. 중첩된 객체 속성에 안전하게 접근할 때 매우 유용합니다. (ES2020부터 사용 가능)const user = { name: "Alice", address: { street: "Main St", city: "Seoul" }, contact: null // contact 속성은 null }; console.log(user.address?.street); // "Main St" console.log(user.contact?.email); // undefined (user.contact가 null이므로 에러 없이 undefined 반환) console.log(user.preferences?.theme); // undefined (user.preferences가 존재하지 않으므로 에러 없이 undefined 반환)
옵셔널 체이닝은 코드의 안정성을 높이고,
if (obj && obj.prop && obj.prop.subProp)
와 같은 복잡한 null/undefined 체크를 간결하게 만듭니다.
자바스크립트 연산자들은 개발자가 프로그램을 유연하고 강력하게 만들 수 있도록 돕는 필수적인 도구입니다. 각 연산자의 정확한 의미와 활용법을 잘 익혀두시면 훨씬 효율적이고 안전한 코드를 작성할 수 있을 거예요!
혹시 특정 연산자의 동작 원리가 더 궁금하시거나, 특정 시나리오에서 어떤 연산자를 사용해야 할지 고민되시나요? 언제든지 질문해주세요!
댓글 없음:
댓글 쓰기