JavaScript 기본 - 기본 연산자와 수학

Leejunyoung·2022년 6월 18일
0

JavaScript

목록 보기
10/49

오늘은 자바스크립트의 기본 연산자와 수학에 대해 공부하겠습니다.
모던 자바스크립트 튜토리얼을 참고하였습니다.
덧셈 +, 곱셈 *, 뺄셈 -과 같은 연산은 학교에서 배워서 이미 알고 있을 것이다.
이런 기본 연산자를 시작으로 학교에선 다루지 않았던 자바스크립트에서만 제공하는 연산자에 대해 알아보자.

용어:'단항', '이항', '피연산자'

연산자에 대해 학습하기 전에, 앞으로 자주 등장하게 될 용어 몇 가지를 정리해 보자.
  • 피연산자(operand)는 연산자가 연산을 수행하는 대상이다. 5 * 2에는 왼쪽 피연산자 5와 오른쪽 피연산자 2, 총 두 개의 피연산자가 있다. '피연산자'는 '인수(argument)'라는 용어로 불리기도 한다.
  • 피연산자를 하나만 받는 연산자는 단항(unary) 연산자라고 부른다. 피연산자의 부호를 뒤집는 단항 마이너스 연산자 - 는 단항 연산자의 대표적인 예이다.
  • 두 개의 피연산자를 받은 연산자는 이항(binary) 연산자라고 부른다. 마이너스 연산자는 아래와 같이 이항 연산자로 쓸 수도 있다.
  • 위와 같이 부호를 반전해주는 단항 마이너스 연산자와 뺄셈에 쓰이는 이항 마이너스 연산자(뺄셈 연산자)는 기호는 같지만 수행하는 연산이 다르다. 두 연산을 구분하는 기준은 피연산자의 개수이다.

    수학

    자바스크립트에서 지원하는 수학 연산자는 다음과 같다.
  • 덧셈 연산자 +
  • 뺄셈 연산자 -
  • 곱셈 연산자 *
  • 나눗셈 연산자 /
  • 나머지 연산자 %
  • 거듭제곱 연산자 **
  • 앞쪽 네 연산자는 설명이 필요 없겠지만, %와 **는 약간의 설명이 필요하다.

    나머지 연산자 %

    나머지 연산자(remainder operator)는 % 기호로 나타내지만, 비율을 나타내는 퍼센트와 관련이 없다. 나머지 연산자를 사용한 표현식 a % b는 a를 b로 나눈 후 그 나머지(remainder)를 정수로 변환해준다.

    거듭제곱 연산자 **

    거듭제곱 연산자(exponentiation operator)를 사용한 a ** b 를 평가면 a를 b번 곱한 값이 변환된다.

    거듭제곱 연산자는 정수가 아닌 숫자에 대해서도 동작한다. 1/2을 사용하면 제곱근을 구할 수 있다.

    이항 연산자 '+'와 문자열 연결

    덧셈 연산자 +는 대개 숫자를 더한 결과를 반환한다. 그런데 이항 연산자 +의 피연자로 문자열이 전달되면 덧셈 연산자는 덧셈이 아닌 문자열을 병합(연결)한다.

    따라서 이항 연산자 +를 사용할 때는 피연산자 중 하나가 문자열이면 다른 하나도 문자열로 변환된다는 점에 주의해야 한다.

    첫 번째 피연산자가 문자열인지, 두 번째 연산자가 문자열인지는 중요하지 않다. 피연산자 중 어느 하나가 문자열이면 다른 하나도 문자열로 변환된다.

    연산은 왼쪽에서 오른쪽으로 순차적으로 진행되기 때문에 이런 결과가 나왔다. 두 개의 숫자 뒤에 문자열이 오는 경우, 숫자가 먼저 더해지고, 그 후 더해진 숫자와 문자열과의 병합이 일어난다.

    이처럼 이항 덧셈 연산자 +는 문자열 연결과 반환이라는 특별한 기능을 제공한다. 다른 산술 연산자가 오직 숫자형의 피연산자만 다루고, 피연산자가 숫자형이 아닌 경우에 그 형을 숫자형으로 바꾸는 것과는 대조적이다.

    뺄셈 -과 나눗셈 / 연산자가 어떻게 문자형 피연산자를 다루는지 보여준다.

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

    덧셈 연산자 +는 이항 연산자뿐만 아니라 단항 연산자로도 사용할 수 있다.

    숫자에 단항 덧셈 연산자를 붙이면 이 연산자는 아무런 동작도 하지 않는다. 그러나 피연산자가 숫자가 아닌 경우엔 숫자형으로의 변환이 일어난다.

    단항 덧셈 연산자는 짧은 문법으로도 Number(...)와 동일한 일을 할 수 있게 해준다.

    개발을 하다 보면 문자열을 숫자로 변환해야 하는 경우가 자주 생긴다. HTML 폼(form) 필드에서 값을 가져왔는데 그 값이 문자형일 때 같이 말이다. 실제로 폼에서 가지고 온 값은 대개 문자열 형태이다.

    이항 덧셈 연산자를 사용하면 아래와 같이 값이 문자열로 변해서 연결될 것이다.

    원하는 대로 값을 더해주려면, 단항 덧셈 연산자를 사용해 피연산자를 숫자형으로 변화시키면 된다.

    위 식을 수학자가 본다면 불필요한 덧셈 기호에 대해 언급하여 식이 이상하다고 지적할 수도 있다. 프로그래머라면 아니겠지만, 위 식은 우리가 의도한 대로 단항 덧셈 연산자가 먼저 문자열을 숫자로 변환시키고, 이항 덧셈 연산자가 그 결과들을 더해주고 있다.

    그런데 왜 이항 덧셈 연산자가 적용되기 전에 단항 덧셈 연산자가 먼저 적용될까? 그 이유는 연산자 우선순위 때문이다.

    연산자 우선순위

    하나의 표현식에 둘 이상의 연산자가 있는 경우, 실행 순서는 연산자의 우선순위(precedence)에 의해 결정된다.

    1+2*2 라는 식이 있을 때 곱셈이 먼저, 그 후에 덧셈이 일어난다는 것을 알고 있을 것이다. 이런 개념이 연산자 우선순위이다. 여기서 곱셈은 덧셈보다 더 높은 우선순위를 가지게 된다.

    자바스크립트에서 정의한 연산자 우선순위가 마음에 들지 않는다면, 괄호를 사용하면 된다. 괄호는 모든 연산자보다 우선순위가 높기 때문에 자바스크립트에서 정의한 우선순위를 무력화시킨다. 표현식 (1+2)*2에서 괄호로 둘러싼 덧셈 연산자가 먼저 수행되는 것과 같다.

    자바스크립트는 다양한 연산자를 제공하는데, 이 모든 연산자엔 우선순위가 매겨져 있다. 우선순위 숫자가 클수록 먼저 실행된다. 순위가 같으면 왼쪽부터 시작해서 오른쪽으로 연산이 수행된다.

    아래는 우선순위 테이블(precedence table)의 일부를 발췌한 표이다. 순서를 기억할 필요는 없지만, 동일한 기호의 단항 연산자는 이항 연산자보다 우선순위가 더 높다는 것에 주목하면 된다.

    '단항 덧셈 연산자'는 우선순위 17로, '(이항) 덧셈 연산자'의 우선순위 13보다 높다.
    표현식 "+apples + +oranges"에서 단항 덧셈 연산자가 덧셈보다 먼저 수행되는 이유가 바로 이 때문이다.

    할당연산자

    무언가를 할당할 때 쓰이는 =도 연산자이다. 이 연산자는 할당(assignment) 연산자라고 불리는데, 우선순위는 3으로 아주 낮다.

    x = 2 * 2 + 1과 같은 표현식에서 계산이 먼저 이뤄지고, 그 결과가 x에 할당되는 이유가 바로 이 때문이다.

    값을 반환하는 할당 연산자

    =는 연산자이기 때문에 흥미로운 함축성을 내포하고 있다.

    자바스크립트에서 대부분의 연산자들은 값을 반환한다. +와 -뿐만 아니라 =역시 값을 반환한다.

    x=value을 호출하면 value가 x에 쓰여지고, 이에 더하여 value가 반환된다.

    할당 연산자의 이런 특징을 이용한 복잡한 표현식을 살펴보자.

    위 예제에서 표현식 (a=b+1)은 a에 값을 할당하고, 그 값인 3을 반환한다.
    그리고 반환 값은 이어지는 표현식에 사용된다.

    괴상한 코드라고 느껴지겠지만, 여러 자바스크립트 라이브러리에서 이런 식으로 할당 연산자를 사용하고 있기 때문에 동작 원리를 이해할 수 있어야 한다.

    다만, 직접 코드를 작성할 땐 이런 방식을 사용하지 않기를 바란다. 이런 트릭을 사용하면 코드가 명확하지 않을 뿐만 아니라 가독성도 떨어지기 때문이다.

    할당 연산자 체이닝

    할당 연산자는 아래와 같이 여러 개를 연결할 수도 있다.

    이렇게 할당 연산자를 여러 개 연결할 경우, 평가는 우측부터 진행된다. 먼저 가장 우측의 2+2가 평가되고, 그 결과가 좌측 c, b, a에 순차적으로 할당된다.
    모든 변수가 단일 값을 공유하게 된다.

    그런데 되도록이면 연산자를 체이닝 하는것 보다 가독성을 위해 아래와 같이 줄을 나눠 코드를 작성하길 권유한다.

    이렇게 작성하면 읽기도 쉽고, 눈을 빠르게 움직이며 코드를 읽을 수 있다. (가독성)

    복합 할당 연산자

    프로그램을 짜다 보면, 변수에 연산자를 적용하고 그 결과를 같은 변수에 저장해야하는 경우가 종종 생긴다.

    이때, += 와 *= 연산자를 사용하면 짧은 문법으로 동일한 연산을 수행할 수 있다.

    이런 '복합 할당' 연산자는 산술 연산자와 비트 연산자에도 적용할 수 있다.
    /=, -= 등의 연산자를 만들 수도 있다.

    복합 할당 연산자의 우선순위는 할당 연산자와 동일하다. 따라서 대부분 다른 연산자가 실행된 후에 복합 할당 연산자가 실행된다.

    증가, 감소 연산자

    숫자를 하나 늘리거나 줄이는 것은 자주 사용되는 연산이다. 자바스크립트에서는 이런 연산을 해주는 연산자를 제공한다.
  • 증가(increment) 연산자 ++는 변수를 1 증가시킨다.
  • 감수(decrement) 연산자 --는 변수를 1 감소시킨다.
  • 중요

    증가/감소 연산자는 변수에만 쓸 수 있다. 5++와 같이 값에 사용하려고 하면 에러가 발생한다.

    ++와 -- 연산자는 변수 앞이나 뒤에 올 수 있다.

  • counter++와 같이 피연산자 뒤에 올 때는, '후위형(postfix form)'
  • ++counter와 같이 피연산자 앞에 올 때는, '전위형(prefix form)'
  • 후위형과 전위형은 피연산자인 counter를 1만큼 증가시켜 준다는 점에서 동일한 일을 한다.

    두 형의 차이는 ++/--의 반환 값을 사용할 때 드러난다.

    자, 다시 상기해 보자. 모든 연산자는 값을 반환한다. 증가/감소 연산자도 마찬가지다. 전위형은 증가/감소 후의 새로운 값을 반환하는 반면, 후위형은 증가/감소 전의 기존 값을 반환한다.

    (*)로 표시한 줄의 전위형 ++counter는 counter를 증가시키고 새로운 값 2를 반환한다.
    따라서 alert는 2를 표시한다.

    (*)로 표시한 줄의 후위형 counter++는 counter를 증가시키긴 하지만, 증가 전의 기존값을 반환한다. 따라서 alert은 1을 표시한다.

    증가, 감소 연산자에 대한 내용 정리

  • 반환 값을 사용하지 않는 경우라면, 전위형과 후위형엔 차이가 없다.
  • 값을 증가시키고 난 후, 증가한 값을 바로 사용하려면 전위형 증가 연산자를 사용하면 된다.
  • 값을 증가시키지만, 증가 전의 기존값을 사용하려면 후위형 증가 연산자를 사용하면 된다.
  • TMI - 다른 연산자 사이의 증가/감소 연산자

    ++/-- 연산자를 표현식 중간에 사용하는 것도 가능하다. 이때, 증가/감소 연산자의 우선순위는 다른 대부분의 산술 연산자보다 높기 때문에, 평가가 먼저 이루어진다.


    위 예시를 아래와 비교해 보자.

    이렇게 코드를 작성하는 게 기술적으로 문제가 있는 것은 아니지만, 한 줄에서 여러 가지 일을 동시에 하고 있기 때문에 코드의 가독성이 떨어진다.

    코드를 읽을 때 눈을 '수직으로' 빠르게 움직이다 보면 counter++와 같은 것을 놓치기 쉽다.
    변수가 증가했다는 것을 놓칠 수 있다.

    '코드 한 줄엔, 특정 동작 하나'에 관련된 내용만 작성하는 게 좋다.

    비트 연산자

    비트 연산자(bitwise operator)는 인수를 32비트 정수로 변환하여 이진 연산을 수행한다.

    이런 비트 조직 관련 연산자는 자바스크립트 뿐만 아니라 대부분의 프로그래밍 언어ㅔ서 지원한다.

    아래는 비트 연산 시 쓰이는 연산자 목록이다.

  • 비트 AND (&)
  • 비트 OR (|)
  • 비트 XOR (^)
  • 비트 NOT (~)
  • 왼쪽 시프트(LEFT SHIFT)(<<)
  • 오른쪽 시프트(RIGHT SHIFT)(>>)
  • 부호 없는 오른쪽 시프트(ZERO-FILL RIGHT SHIFT)(>>>)
  • 비트 연산자는 저수준(2진 표현)에서 숫자를 다뤄야 할 때 쓰이므로 흔하게 쓰이진 않는다. 웹 개발 시엔 이런 일이 자주 일어나지 않기 때문에 비트 연산자를 만날 일은 거의 없다. 그렇긴 해도 암호를 다뤄야 할 땐 비트 연산자가 유용하기 때문에 때가 되면 MDN의 비트 연산자 문서를 보는것이 좋다.

    쉼표 연산자

    쉼표 연산자(comma operator) , 는 좀처럼 보기 힘들고, 특이한 연산자 중 하나이다. 코드를 짧게 쓰려는 의도로 가끔 사용된다. 이런 코드를 만났을 때, 어떤 연산 결과가 도출되는지 알아야 하므로 쉼표 연산자에 대해 알아보자.

    쉼표 연산자 , 는 여러 표현식을 코드 한 줄에서 평가할 수 있게 해준다. 이때 표현식 각각이 모두 평가되지만, 마지막 표현식의 평가 결과만 반환되는 점에 유의해야 한다.

    위 예시에서 첫 번째 표현식 1+2은 평가가 되지만 그 결과는 버려진다. 3+4만 평가되며 a에 할당된다.

    TMI - 쉼표의 우선순위는 매우 낮다.

    쉼표 연산자의 연산자 우선순위는 매우 낮다. 할당 연산자 = 보다 더 낮다. 따라서 위 예시에선 괄호가 중요한 역할을 한다.

    괄호가 없으면 a=1+2,3+4에서 +가 먼저 수행되어 a=3, 7이 된다. 할당 연산자 = 는 쉼표 연산자보다 우선순위가 높기 때문에 a=3이 먼저 실행되고, 나머지 (7)는 무시된다.
    (a=1+2),3+4를 연산한 것처럼 된다.

    이렇게 마지막 표현식을 제외한 모든 것을 버리는 연산자는 어디서 사용되는 걸까?

    여러 동작을 하나의 줄에서 처리하려는 복잡한 구조에서 이를 사용한다.

    쉼표 연산자를 사용한 트릭은 여러 자바스크립트 프레임워크에서 볼 수 있다. 이 연산자의 사용 빈도가 높지 않지만, 언급하고 넘어가는 이유이다. 쉼표 연산자는 코드 가독성에 도움이 되지 않는다. 따라서 곰곰이 생각해 본 후, 진짜 필요한 경우에만 사용하는 것을 권장한다.

    profile
    안녕하세요

    0개의 댓글