본문 바로가기
언어

Basic operators, maths (JavaScript)

by adawn 2025. 3. 10.

출처 : 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