[모던 자바스크립트 튜토리얼] 2.8 기본 연산자와 수학

개발견 배도르만·2023년 2월 26일
0
post-thumbnail

기본 연산자와 수학

연산자는 덧셈, 뺄셈, 곱셈 등을 수행하게 하는 문자이다. (+, -, *, /)
이러한 기본연산자 외에도 자바스크립트에서 제공하는 연산자도 존재한다.

용어

1) 피연산자(operand)

연산자가 연산을 수행하는 대상.
5 * 2에는 왼쪽 피연산자 5와 오른쪽 피연산자 2, 총 두 개의 피연산자.
인수(argument)라는 용어로 불리기도 함.

2) 단항 연산자(unary operator)

피연산자를 하나만 받는 연산자.
대표적인 예로 피연산자의 부호를 뒤집는 단항 마이너스 연산자 (-)가 있다.

let x = 1;
x = -x;
alert( x ); // -1

3) 이항 연산자(binary operator)

두 개의 피연산자를 받는 연산자.
마이너스 연산자는 아래와 같이 이항 연산자로 쓸 수도 있다.

let x = 1, y = 3;
alert( y - x ); // 2, 이항 마이너스 연산자는 뺄셈 기능

위와 같이 부호를 반전해주는 단항 마이너스 연산자와 뺄셈에 쓰이는 이항 마이너스 연산자(뺄셈 연산자)는 기호는 같지만 수행하는 연산이 다르다.
두 연산을 구분하는 기준은 피연산자의 개수이다.

4) 수학

자바스크립트에서 지원하는 수학 연산자.

덧셈 연산자 +
뺄셈 연산자 -
곱셈 연산자 *
나눗셈 연산자 /
나머지 연산자 %
거듭제곱 연산자 **
앞쪽 네 연산자는 일반적인 사칙연산을 수행한다.
%와 ** 또한 수학에서 일반적인 개념이지만 표현방식이 다르다.

  • 나머지 연산자(remainder operator) %
    : a % b의 경우 a를 b로 나눈 나머지를 정수로 반환

    alert( 5 % 2 ); // 5를 2로 나눈 후의 나머지인 1을 출력
    alert( 8 % 3 ); // 8을 3으로 나눈 후의 나머지인 2를 출력
  • 거듭제곱 연산자(exponentiation operator) **
    : a ** b의 경우 a를 b번 곱한 값을 반환.

    alert( 2 ** 2 ); // 4  (2 * 2)
    alert( 2 ** 3 ); // 8  (2 * 2 * 2)
    alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2)
    alert( 8 ** (1/3) ); // 2 (1/3 거듭제곱은 세제곱근)

5) 이항연산자 +와 문자열 연결

덧셈 연산자 +의 피연산자.
문자열이 전달되면 덧셈 연산자는 덧셈이 아닌 문자열을 병합(연결)한다.

let s = "my" + "string";
alert(s); // mystring

이 때, 피연산자 중 하나가 문자열이면 다른 하나도 문자열로 변환된다.

alert( '1' + 2 ); // "12"
alert(2 + 2 + '1' ); // 연산은 왼쪽에서 오른쪽으로 진행되기 때문에 '221'이 아니라 '41'이 출력

문자열 연결 기능은 +의 특별한 기능이다.
-, *, / 연산자의 피연산자로 문자열이 들어오면 +처럼 숫자를 문자로 변환하는 것이 아닌 문자를 숫자로 변환하여 연산을 수행한다.

alert( 6 - '2' ); 
// 4, '2'를 숫자로 바꾼 후 연산
alert( '6' / '2' ); // 3, 두 피연산자가 숫자로 바뀐 후 연산

6) 단항연산자 +와 숫자형으로의 변환

덧셈 연산자 +는 단항연산자로도 사용 가능하다.
피연산자가 숫자인 경우 단항연산자 +는 아무 동작을 하지 않지만 피연산자가 숫자가 아닌 경우 피연산자를 숫자형으로 변환한다.

// 숫자에는 아무런 영향을 미치지 않는다.
let x = 1;
alert( +x ); // 1

let y = -2;
alert( +y ); // -2

// 숫자형이 아닌 피연산자는 숫자형으로 변환한다.
alert( +true ); // 1
alert( +"" );   // 0

짧은 문법으로도 Number(...)와 동일한 일을 할 수 있게 해주는 셈이다.

let apples = "2";
let oranges = "3";

alert( apples + oranges ); // 23
alert( +apples + +oranges ); // 5

위 예제의 마지막 alert()의 인자엔 연산자 +가 세 번 포함된다. 그런데 어떻게 단항연산자 +부터 적용되어 숫자로 변환되고 그 이후에 이항연산자 +가 덧셈을 수행하는 걸까? 연산자 우선순위 때문이다.

7) 연산자 우선순위

하나의 표현식에 둘 이상의 연산자가 있는 경우, 실행 순서는 연산자의 우선순위(precedence)에 의해 결정된다. 사칙연산에서 곱셈과 나눗셈이 덧셈과 뺄셈보다 먼저 수행된다는 것이 대표적인 예이다. 곱셈, 나눗셈이 덧셈, 뺄셈보다 높은 우선순위를 갖기 때문이다.
이 우선순위에 의한 연산 순서를 조정하는 것이 괄호이다. 괄호는 모든 연산자보다 우선순위가 높기 때문에 연산 순서를 의도적으로 조정할 수 있다.

아래는 우선순위 테이블의 일부이다.(출처)

8) 할당 연산자

값을 변수에 할당할 때 사용하는 연산자 (=)
우선순위가 3으로 아주 낮은 편이기 때문에 할당 전에 모든 계산을 거치고 계산된 값이 변수 등에 할당되는 것이다.

  • 값을 반환하는 연산자
    단순히 할당의 기능만 수행하는 것이 아니라 타 연산자처럼 반환의 기능 또한 가지고 있다.

    let a = 1;
    let b = 2;
    
    let c = 3 - (a = b + 1);
    
    alert( a ); // 3
    alert( c ); // 0

    하지만 코드가 명확하지 않고 가독성이 떨어지기 때문에 권장되지 않는 방법이다.

  • 할당 연산자 체이닝

    let a, b, c;
    
    a = b = c = 2 + 2;
    
    alert( a ); // 4
    alert( b ); // 4
    alert( c ); // 4

    할당 연산자 여러 개를 연결하여 사용할 수도 있으나 마찬가지로 권장되지 않는다.

9) 복합 할당 연산자

변수에 연산자를 적용한 결과를 같은 변수에 저장할 때 복합 할당 연산자 +=, *= 등을 사용하여 코드 길이를 줄일 수 있다. 우선순위는 할당 연산자와 같으므로 다른 연산자 실행 후에 할당된다.

let n = 2;
n = n + 5;
n = n * 2;
let n = 2;
n += 5; // n은 7이 된다(n = n + 5와 동일).
n *= 2; // n은 14가 된다(n = n * 2와 동일)

alert( n ); // 14

10) 증가•감소 연산자

변수의 숫자를 1만큼 증가 또는 감소시키는 연산자(++, --). 전위형과 후위형이 있다.
반환값이 없는 경우에는 전위형과 후위형에 차이가 없지만

반환값이 있는 경우

전위형은 반환 전 연산을 진행하여 연산 처리된 값을 반환하고

후위형은 기존의 값을 반환 후 연산을 진행한다.

  • 증가 연산자 후위형
    let counter = 2;
    alert( counter++ ); // 2
  • 감소 연산자 전위형
    let counter = 2;
    alert( --counter ); // 1

증가•감소 연산자는 다른 연산자와 함께 사용 가능하지만 코드의 가독성이 떨어지기 때문에 구분해서 사용하는 편이 좋다.
let counter = 1;
alert( 2 * counter++ ); // 가독성 떨어지는 편

let counter = 1;
alert( 2 * counter );
counter++; // 가독성 좋은 편

11) 비트 연산자(bitwise operator)

인수를 32비트 정수로 변환하여 이진 연산을 수행.

  • 비트 AND ( & )
  • 비트 OR ( | )
  • 비트 XOR ( ^ )
  • 비트 NOT ( ~ )
  • 왼쪽 시프트(LEFT SHIFT) ( << )
  • 오른쪽 시프트(RIGHT SHIFT) ( >> )
  • 부호 없는 오른쪽 시프트(ZERO-FILL RIGHT SHIFT) ( >>> )

주로 저수준(2진 표현)에서 숫자를 다뤄야 할 때 쓰이므로 흔하게 쓰이진 않지만 암호를 다룰 때 유용하게 쓰인다.

12) 쉼표 연산자(comma operator)

여러 표현식을 한 줄의 코드로 평가할 수 있게 하는 연산자(,)
표현식 각각이 모두 평가되지만, 마지막 표현식의 평가 결과만 반환된다.

let a = (1 + 2, 3 + 4);

alert( a ); // 7 (3 + 4의 결과)

쉼표 연산자는 우선순위가 할당 연산자(=)보다 낮으므로 대부분의 다른 연산이 처리된 후 진행된다.

대표적인 사용 예시로 for문의 조건부가 있다.

// 한 줄에서 세 개의 연산이 수행됨
for (a = 1, b = 3, c = a * b; a < 10; a++) {
 ...
}

✍️ 정리

일반적으로 사용하지만 전부 우선순위에 따라 처리되기 때문에 정해진 결과가 나오는 것이다. '컴퓨터는 거짓말을 하지 않는다.'

profile
네 발 개발 개

0개의 댓글