출처 : https://javascript.info/operators
Basic operators, maths
javascript.info
기본 연산자, 수학
우리는 학교에서 덧셈 (+) , 곱셈 (*) , 뺄셈(-) 등 여러 연산자를 배웠음.
이 챕터에서는 간단한 연산자부터 시작해 , 학교 수학에서는 다루지 않는 자바스크립트 고유의 측면들에 집중함.
용어: “unary”, “binary”, “operand”
피연산자(operand)
연산자가 적용되는 대상임. 예를 들어 5 * 2 에서는 왼쪽 피연산자는 5 온른쪽 피연산자는 2 임.
때때로 이를 "인수(arguments)"라고 부르기도 함.
연산자(operator)
단항(unary) 연산자는 피연산자가 하나인 연산자임.
예를 들어, 단항 부정 연산자 -는 숫자의 부호를 반전시킴.
let x = 1;
x = -x;
alert( x ); // -1, 단항 부정이 적용됨
이항(binary) 연산자는 두 개의 피연산자를 갖음.
같은 기호인 -도 이항으로 사용될 수 있음.
let x = 1, y = 3;
alert( y - x ); // 2, 이항 뺄셈이 값을 빼줌
위 예제에서는 기호는 같지만 , 하나는 부호를 반전시키는 단항 연산자이고 다른 하나는 두 숫자 간의 뺄셈을 수행하는 이항 연산자임.
여기서 말하는 단항 , 이항은 피연산자의 개수를 이야기하는 듯함.
수학 연산
자바스크립트에서 지원하는 수학 연산은 다음과 같음.
덧셈 +
뺄셈 -
곱셈 *
나눗셈 /
나머지 %
지수 연산 **
처음에 네 연산자는 직관적이지만 %와 **에 대해선 추가 설명이 필요함.
나머지 연산자
나머지 연산자 %는 모양과 달리 퍼센트(%)와 관련이 없음.
a % b의 결과는 a를 b로 정수 나눗셈했을 때 남는 나머지임.
예를 들어 :
alert( 5 % 2 ); // 1, 5를 2로 나눈 나머지
alert( 8 % 3 ); // 2, 8을 3으로 나눈 나머지
alert( 8 % 4 ); // 0, 8을 4로 나눈 나머지
지수 연산자 **
지수 연산자 a ** b는 a를 b로 제곱함.
학교 수학에서는 이를 a ^b (또는 ab)라고 표현함.
예를 들어 :
alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
수학에서처럼 지수 연산자는 정수가 아닌 숫자에도 적용됨.
예를 들어, 제곱근은 1/2 제곱과 동일함.
alert( 4 ** (1/2) ); // 2 (1/2 제곱은 제곱근과 같음)
alert( 8 ** (1/3) ); // 2 (1/3 제곱은 세제곱근과 같음)
문자열 연결과 이항 +
보통, + 연산자는 숫자를 더함.
하지만 , 이항 +가 문자열에 적용되면 두 문자열을 이어 붙임. (concatenation)
예를 들어 :
let s = "my" + "string";
alert(s); // mystring
만약 피연산자 중 하나가 문자열이면 , 다른 피연산자도 문자열로 변환됨.
예 :
alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
둘 다 숫자지만 문자열로 변환되어 그냥 합쳐지는 걸 볼 수 있음.
더 복잡한 예 :
alert(2 + 2 + '1' ); // "41" → 먼저 2+2가 계산되어 4가 되고, 그 후 "1"과 연결됨
alert('1' + 2 + 2); // "122" → 첫 피연산자가 문자열이므로 나머지도 문자열로 처리됨
이항 +는 이러한 방식으로 문자열을 처리하는 유일한 연산자임.
다른 산술 연산자는 항상 피연산자들을 숫자로 변환하여 작업함.
이항 +만 .
예를 들어 :
alert( 6 - '2' ); // 4, '2'가 숫자로 변환됨
alert( '6' / '2' ); // 3, 두 피연산자 모두 숫자로 변환됨
숫자 변환과 단항 +
+ 연산자는 두 가지 형태가 있음.
앞서 사용한 이항 형태와는 달리 , 단항 형태의 +는 피연산자가 숫자가 아닌 경우 숫자로 변환함.
숫자가 아닌 것을 숫자로 변환
// 숫자에는 아무런 효과 없음
let x = 1;
alert( +x ); // 1
let y = -2;
alert( +y ); // -2
// 숫자가 아닌 값을 숫자로 변환
alert( +true ); // 1
alert( +"" ); // 0
단항 +는 실제로 Number(...)와 동일하게 동작하지만 더 간결함.
문자열을 숫자로 변환할 필요는 매우 빈번함.
예를 들어 HTML 폼 필드에서 값을 읽어오면 보통 문자열로 반환됨.
이러한 값들을 덧셈하려고 할 떄 이항 +는 단순히 문자열을 이어 붙여 버림.
예 :
let apples = "2";
let oranges = "3";
alert( apples + oranges ); // "23", 이항 `+`는 문자열 연결
숫자로 취급하고 싶다면 변환 후에 더해야 함.
alert( +apples + +oranges ); // 5
// 또는 더 긴 형태:
alert( Number(apples) + Number(oranges) ); // 5
수학자 입장에서는 여러 개의 단항 +가 남발되는 것이 이상해 보일 수 있지만 프로그래머 입장에서는 단항 +가 먼저 적용되어 문자열을 숫자로 변환한 후 이항 +가 덧셈을 수행하기 때문에 문제 없음.
왜 단항 +가 이항 +보다 먼저 적용이 될까?
그 이유는 단항 연산자의 우선순위가 더 높기 때문.
연산자 우선순위
표현식에 여러 연산자가 있는 경우, 실행 순서는 연산자들의 우선순위(preference)에 따라 결정됨.
예를 들어 , 1 + 2 * 2에서 곱셈이 덧셈보다 먼저 계산되야 한다는 것을 우리는 학교에서 배웠음.
만약 기본 순서가 마음에 들지 않는다면 괄호를 사용하여 우선순위를 변경할 수 있음.
예: (1+2) * 2
자바스크립트에는 많은 연산자가 있으며, 각 연산자는 고유의 우선순위 번호를 가지고 있음.
숫자가 클수록 우선순위가 높아 먼저 실행되며 , 우선순위가 같으면 왼쪽에서 오른쪽 순으로 평가됨.
다음은 우선순위 테이블의 일부 발췌임.
(모두 외울 필요는 없지만, 단항 연산자가 해당 이항 연산자보다 높은 우선순위를 가진다는 점에 주의):
| 우선순위 | 이름 | 기호 |
| … | … | … |
| 14 | 단항 플러스 | + |
| 14 | 단항 부정 | - |
| 13 | 지수 연산 | ** |
| 12 | 곱셈 | * |
| 12 | 나눗셈 | / |
| 11 | 덧셈 | + |
| 11 | 뺄셈 | - |
| … | … | … |
| 2 | 할당 | = |
| … | … | … |
예를 들어, 단항 +의 우선순위(14)가 이항 덧셈 (11)보다 높기 때문에 표현식 +apples + oranges에서는 단항 +가 먼저 작동함.
할당
할당 연산자 = 도 연산자임.
우선순위 테이블에서 매우 낮은 우선순위 (2)를 가지고 있음.
예를 들어
let x = 2 * 2 + 1;
alert( x ); // 5
에서 덧셈과 곱셈이 먼저 계산된 후 = 가 실행되어 결과가 변수 x에 저장됨.
할당 연산자 = 는 값을 반환함
=가 연산자라는 사실은 흥미로운 결과를 가져옴.
자바스크립트의 모든 연산자는 값을 반환하며 이는 +와 - 뿐만 아니라 =에도 해당됨.
x = value는 value를 x에 저장한 후 그 value를 반환함.
예를 들어, 복잡한 표현식의 일부로 할당을 사용할 수 있음.
let a = 1;
let b = 2;
let c = 3 - (a = b + 1);
alert( a ); // 3
alert( c ); // 0
위 예제에서 (a = b + 1)의 결관느 a에 할당된 값 (즉 , 30 )이며 , 이후 표현식에서 사용됨.
재미있는 코드처럼 보일 수 있지만
자바스크립트 라이브러리에서 때때로 이러한 방식이 사용되므로 그 동작을 이해할 필요가 있음.
다만 가독성을 위해 이런 방식은 사용하지 않는 것이 좋음.
할당 체이닝 (Chaining assignments)
또 다른 흥미로운 기능은 할당을 연속해서 연결(chaining)할 수 있다는 점.
let a, b, c;
a = b = c = 2 + 2;
alert( a ); // 4
alert( b ); // 4
alert( c ); // 4
체인 할당은 오른쪽에서 왼쪽으로 평가됨.
먼저 , 오른쪽 표현식 2 + 2 가 평가되고 그 결과가 차례대로 변수 c , b , a에 할당되어 모든 변수가 동일한 값을 갖게 됨.
가독성을 위해서는 아래와 같이 여러 줄로 나누어 작성하는 것이 좋음.
c = 2 + 2;
b = c;
a = c;
제자리 수정 (Modify - in - place)
변수에 연산자를 적용해 그 결과를 다시 같은 변수에 저장할 떄가 많음.
예를 들어 :
let n = 2;
n = n + 5;
n = n * 2;
이 표현은 아래와 같이 줄일 수 있음.
let n = 2;
n += 5; // n = n + 5와 동일, 이제 n은 7
n *= 2; // n = n * 2와 동일, 이제 n은 14
alert( n ); // 14
나머지 산술 및 비트 연산자에도 /= , -= 등의 짧은 수정 = 할당 연산자가 있음.
이러한 연산자는 일반 할당 연산자와 같은 우선순위를 가지므로 대부분의 계산 후에 실행됨.
let n = 2;
n *= 3 + 5; // 오른쪽 부분이 먼저 평가됨 → n *= 8
alert( n ); // 16
증감 연산자(Increment / Decrement)
숫자를 1씩 증가시키거나 감소시키는 것은 매우 흔한 연산임.
따라서 이를 위한 특별한 연산자가 마련되어 있음.
증가 연산자 ++
증가 연산자 ++는 변수를 1 증가시킴:
let counter = 2;
counter++; // counter = counter + 1과 동일하지만 더 짧음
alert( counter ); // 3
감소 연산자 --
감소 연산자 --는 변수를 1 감소시킴:
let counter = 2;
counter--; // counter = counter - 1과 동일하지만 더 짧음
alert( counter ); // 1
중요 : 증감 연산자는 변수에만 적용 가능
예를 들어 , 5 ++ 와 같이 숫자 리터럴에 적용하면 에러가 발생함.
증감 연산자 ++ 와 --는 변수의 앞이나 뒤에 올 수 있음.
후위 (postfix) 형태 : counter++
전위(prefix)형태: ++counter
두 형태 모두 변수의 값을 1 증가시키지만 , 반환하는 값에는 차이가 있음.
전위와 후위의 차이
모든 연산자는 값을 반환함. 증감 연산자도 예외는 아님.
전위 형태(++counter)
변수의 값을 먼저 증가시키고 , 증가된 새로운 값을 반환함.
후위 형태(counter++)
변수의 값을 증가시키지만, 증가 이전의 값을 반환함.
예를 들어 :
let counter = 1;
let a = ++counter; // 전위 형태: counter가 먼저 증가하여 2가 되고, 2를 반환
alert(a); // 2
반면 :
let counter = 1;
let a = counter++; // 후위 형태: a는 증가 전의 값 1을 받고, 그 후 counter는 2가 됨
alert(a); // 1
요약하면 :
증감 연산자의 결과를 사용하지 않는다면 전위와 후위 모두 같은 효과를 냄.
let counter = 0;
counter++;
++counter;
alert( counter ); // 2
만약 연산 결과를 바로 사용해야 한다면 전위 형태를 사용
let counter = 0;
alert( ++counter ); // 1
만약 증감 전에 변수의 값을 사용해야 한다면 , 후위 형태를 사용
let counter = 0;
alert( counter++ ); // 0
다른 연산자와 함께 사용되는 증감 연산자
증감 연산자는 다른 연산자와 함께 표현식 내에서 사용할수도 있음.
이들의 우선순위는 대부분의 산술 연산자보다 높음.
예를 들어 :
let counter = 1;
alert( 2 * ++counter ); // 4
비교 :
let counter = 1;
alert( 2 * counter++ ); // 2, counter++는 증가 전의 값을 반환하기 때문
비록 기술적으로는 괜찮더라도 , 한줄에 여러 작업을 수행하면 코드 가독성이 떨어질 수 있으므로 한 줄에는 한가지 작업만 수행하는 것을 권장.
let counter = 1;
alert( 2 * counter );
counter++;
비트 연산자(Bitwise operators)
비트 연산자는 피연산자들을 32비트 정수로 취급하고 , 그들의 이진수 표현을 기반으로 연산함.
이 연산자들은 자바스크립트에 국한된 것이 아니라 대부분의 프로그래밍 언어에서 지원됨.
비트 연산자의 목록 :
AND : &
OR: |
XOR : ^
NOT : ~
왼쪽 시프트 : <<
오른쪽 시프트 : >>
제로 채움 오른쪽 시프트 : >>>
이러한 연산자들은 숫자를 비트 단위에서 조작할 필요가 있을 떄 매우 드물게 사용됨.
웹 개발에선 잘 사용되지 않지만 암호화 등 특별한 분야에서는 유용할 수 있음.
필요할 때 MDN의 Bitwise Operators 챕터를 참고.
콤마 연산자 (Comma)
콤마 연산자 , 는 가장 드물고 특이한 연산자 중 하나임.
때로는 코드를 더 짧게 작성하기 위해 사용되므로 그 동작을 이해할 필요가 있음.
콤마 연산자는 여러 표현식을 콤마 (,)로 구분하여 평가할 수 있으며
각 표현식은 평가되지만 마지막 표현식의 결과만 반환됨.
예를 들어 :
let a = (1 + 2, 3 + 4);
alert( a ); // 7 (마지막 표현식 3 + 4의 결과)
여기서 첫 번째 표현식 1 + 2 는 평가되어 결과가 버려지고
그 다음 3 + 4가 평가되어 반환됨.
주의 :
콤마 연산자는 매우 낮은 우선 순위를 가지므로 , 할당 연산자 ( = ) 보다도 낮음.
그래서 위 예제에서는 괄호가 필수임.
괄호가 없으면 , 예를 들어 a = 1 + 2 , 3 + 4는
먼저 + 연산이 수행되어 a = 3, 7이 되고
할당 연산자 = 는 a에 3을 할당한 후 나머지는 무시됨.
즉 이는 (a = 1 + 2), 3 + 4 와 같음.
왜 마지막 표현식을 제외한 나머지 결과를 버리는 연산자가 필요할까 ?
때때로 여러 작업을 한 줄에 넣기 위해 복잡한 구조에서 사용되기도 함.
// 한 줄에 세 가지 작업 수행
for (a = 1, b = 3, c = a * b; a < 10; a++) {
...
}
이러한 트릭은 많은 자바스크립트 프레임 워크에서 사용되지만
보통 코드의 가독성을 높이지 않으므로 사용 전에 신중히 고려해야 함.
과제
1. 후위와 전위 형태
아래 코드 실행 후 변수 a , b ,c와 d의 최종 값은 무엇일까?
let a = 1, b = 1;
let c = ++a; // ?
let d = b++; // ?
a = 2
b = 2
c = 2
d = 1
2. 할당 결과
아래 코드 실행 후 변수 a와 x의 값은 ?
let a = 2;
let x = 1 + (a *= 2);
a = 4
x = 5
3. 형 변환
다음 표현식들의 결과는 무엇일까?
"" + 1 + 0
"" - 1 + 0
true + false
6 / "3"
"2" * "3"
4 + 5 + "px"
"$" + 4 + 5
"4" - 2
"4px" - 2
" -9 " + 5
" -9 " - 5
null + 1
undefined + 1
" \t \n" - 2
"10"
-1
1 + 0 -> 1 true (1) false(0)
2
6
"9px"
"$45"
2
NaN (숫자로 변환할 때 4는 변환되지만 px는 변환되지 않으므로 )
"-9+5"
-14
1
NaN
-2
4. 덧셈 수정하기
다음 코드는 사용자에게 두 개의 숫자를 입력받아 그 합을 출력함.
하지만 , 기본 프롬프트 값의 경우 출력 결과가 12로 잘못 나타남.
왜 그럴까? 이를 수정하여 결과가 3이 되도록 고치기 .
let a = prompt("First number?", 1);
let b = prompt("Second number?", 2);
alert(a + b); // 12
let a = prompt("First number?", 1);
let b = prompt("Second number?", 2);
alert(+a + + b); // 12
+를 하나씩 써주면 되는 줄 알았는데 연산자도 추가해주어야 헀다.
또는 prompt 앞에 +를 추가하거나?
'언어' 카테고리의 다른 글
| Conditional branching: if, '?' (JavaScript) (0) | 2025.03.12 |
|---|---|
| Comparisons (JavaScript) (0) | 2025.03.10 |
| Type Conversions (JavaScript) (0) | 2025.03.10 |
| Interaction: alert, prompt, confirm (JavaScript) (0) | 2025.03.10 |
| Data types (JavaScript) (0) | 2025.03.10 |