새소식

Study/JavaScript

[모던 JavaScript] 코어 자바스크립트 - 자바스크립트 기본 - 8. 기본 연산자와 수학

  • -

덧셈 +, 곱셈 *, 뺄셈 - 연산자와 자바스크립트에서만 제공하는 연산자에 대해

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

- 피연산자(operand)

   연산자가 연산을 수행하는 대상, 5*2면 피연산자가 두 개(5, 2)

   피연산자는 인수(argument)로 불리기도 한다.

 

- 단항(unary)

   피연산자를 하나만 받는 연사자를 단항 연산자 라고 부른다.

   피연산자의 부호를 뒤집는 단항 마이너스 연산자 - 는 단항 연산자의 대표적인 예

let x = 1;

x = -x;
alert( x ); // -1, 단항 마이너스 연산자는 부호를 뒤집는다.

 

- 이항(binary)

   두 개의 피연산자를 받는 연산자를 이항 연산자 라고 부른다.

   마이너스 연산자도 이항 연산자로 쓸 수 있다.

let x = 1, y = 3;
alert( y - x ); // 2, 이항 마이너스 연산자는 뺄셈을 해준다.

 

수학

자바스크립트의 수학 연산자 종류

1. 덧셈 연산자 +

2. 뺄셈 연산자 -

3. 곱셈 연산자 *

4. 나눗셈 연산자 /

5. 나머지 연산자 %

6. 거듭제곱 연산자 **

 

나머지 연산자 %

나머지 연산자(remainder operator)는 % 기호로 나타내지만 퍼센트와는 관련이 없다!

a % b에서 a를 b로 나눈 나머지(remainder)를 정수로 반환해준다.

alert( 5 % 2 ); // 5를 2로 나눈 후의 나머지인 1을 출력
alert( 8 % 3 ); // 8을 3으로 나눈 후의 나머지인 2를 출력

처음 배울 때는 나머지 연산자가 조금 헷갈렸었는데 이젠 알고리즘 문제에서 유용하게 쓰는...❤

 

거듭제곱 연산자 **

a ** b는 a를 b번 곱한 값이 된다.

console.log( 2 ** 2 ); // 4  (2 * 2)
console.log( 2 ** 3 ); // 8  (2 * 2 * 2)
console.log( 2 ** 4 ); // 16 (2 * 2 * 2 * 2)

console.log( 4 ** (1/2) ); // 2 (1/2 거듭제곱은 제곱근)
console.log( 8 ** (1/3) ); // 2 (1/3 거듭제곱은 세제곱근)

정수가 아닌 값에도 된다.

 

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

덧셈 연산자는 숫자를 더한 결과를 반환하는데 문자열로 전달이 되면 문자열을 병합(연결)한다.

console.log('hello' + 'world') // helloworld
console.log('2' + 1) // 21

하나가 문자열이면 다른 하나도 문자열로 변환돼서 문자열 2와 숫자 1의 덧셈은 문자열 21이 된다.

 

console.log(2 + 2 + '2' + '1') // 421

앞에서 숫자들끼리의 연산이 가능하면 숫자들끼리 먼저 더해지고 뒤에 문자열이 붙는다.

따라서 위의 연산은 2221 이 아니라 421

덧셈 연산자 + 는 문자열 연결과 변환이라는 특별한 기능을 제공하지만

다른 산술 연산자는 오직 숫자형의 피연산자만 다루고 숫자형이 아닌 경우 숫자형으로 바꾼다.

console.log('6' / '2') // 3
console.log('6' - '2') // 4
console.log('6' * '2') // 12
console.log('6' ** '2') // 36

console.log(2 * 2 * '2' + '1') // "81"

 

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

덧셈 연산자는 이항 연산자뿐만 아니라 단항 연산자로도 사용 가능.

숫자형에 덧셈 연산자를 붙이면 아무 동작도 하지 않지만, 숫자가 아닌 경우엔 숫자형으로 변환해준다.

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

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

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

단항 덧셈 연산자는 짧은 문법으로도 Number(value)와 같은 일을 해준다.

폼(form)등을 이용해서 값을 받아서 숫자로 변환해줘야 할 때나 알고리즘 등을 풀 때

Number(value) 대신 +value 로 적고 코드를 실행시킬 수 있다. (프로그래머스 기준 +value가 조금 더 빨랐다.)

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

// 이항 덧셈 연산자가 적용되기 전에, 두 피연산자는 숫자형으로 변화한다.
alert( +apples + +oranges ); // 5

// `Number(...)`를 사용해서 같은 동작을 하는 코드를 작성할 수 있지만, 더 길다.
// alert( Number(apples) + Number(oranges) ); // 5

이런 재미있는 식도 있다. 이항 연산자가 적용되기 전에 단항 연산자가 먼저 적용된다.

둘다 같은 덧셈 연산자 인데! 이유는 아래에서

 

연산자 우선순위

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

1 + 2 * 2 의 경우 우리는 덧셈 먼저 해야된다는 걸 알고 있다. 이런 개념이 바로 연산자 우선순위이다.

연산자 우선 순위 표가 나와있는 링크

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence

할당( = ) < 뺄셈( - ) = 덧셈( + ) < 나눗셈( / ) = 곱셈( * ) < 지수( ** ) < 단항 덧셈(+) = 단항 부정( - ) <<< 괄호

자주 나오는 것들의 우선 순위, 왼쪽으로 갈수록 우선 실행 된다.

동일한 기호의 이항 연산자보다 단항 연산자가 우선 순위가 더 높다. (먼저 실행된다)

 

할당 연산자 (assignment, =)

계산이 먼저 이뤄지고 맨 마지막에 할당되는 이유가 우선 순위가 3으로 아주 낮기 때문.

 

값을 반환하는 할당 연산자

- 대부분 연산자들은 값을 반환한다. +, -, = 셋 다

x = value를 호출하면 x에 value가 쓰여지고 value가 반환됨

let a = 1;
let b = 2;

let c = 3 - (a = b + 1); // a는 b+1 3이 되고 3-3이 돼서 c가 0

alert( a ); // 3
alert( c ); // 0

여러 라이브러리에서 이런 식으로 할당 연산자를 사용하고 있기 때문에 동작 원리를 이해할 수 있어야 한다.

직접 코드를 작성할 땐 이러지 말기... 코드가 명확하지도 않고 가독성도 떨어짐

 

할당 연산자 체이닝

let a, b, c;

a = b = c = 2 + 2;

alert( a ); // 4
alert( b ); // 4
alert( c ); // 4

이렇게 여러 개를 연결(체이닝) 할 수 있다.

할당 연산자 여러 개를 연결한 경우, 오른쪽부터 진행됨

그리고 c, b, a 순서로 할당된다.

이것 역시 가독성을 위해 체이닝 대신 이런 식으로 작성 하기

c = 2+2
b = c
a = c

 

복합 할당 연산자

연산한 변수에 연산한 결과를 저장해야 할 경우

let n = 2
n+= 5 // n = n + 5와 동일

console.log(n) // 7

+= *= 이런 식으로 연산자를 사용할 수 있다. 많이 쓰이고 n = n + 5보다 시간도 적게 걸린다.

우선순위는 할당 연산자와 같다. 대부분 다른 연산자가 실행된 후 복합 할당 연산자가 실행된다.

let n = 2

n *= 3 + 5
console.log(n) // 16 (*= 오른쪽이 먼저 평가되므로 n *= 8이 된다.)

 

증가•감소 연산자

숫자 하나를 늘리거나 줄이는 연산자 

증가(increment) 연산자 ++

let number = 7
number++
console.log(number) // 8

감소(devrement) 연산자 --

let number = 7
number--
console.log(number) // 6

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

number++ 와 같이 피연산자 뒤에 올 때는 후위형(postfix form)이라고 부른다.

++number 와 같이 피연산자 앞에 올 때는 전위형(prefix from)이라고 부른다.

 

모든 연산자는 값을 반환한다. 전위형은 증가/감소 후의 새로운 값을 반환하고

후위형은 증가/감소 전의 기존 값을 반환한다.

let cnt = 1
let a = ++cnt

console.log(a) // 2, cnt는 2

전위형은 이렇게 cnt를 증가시키고 새로운 값을 반환한다. 그래서 a에는 2가 저장된다.

let cnt = 1
let a = cnt++

console.log(a) // 1, cnt는 2

후위형은 cnt를 증가시키고 기존 값을 반환한다. a는 1이 저장된다.

 

증가, 감소 연산자 최종 정리

// 반환 값을 사용하지 않는 경우 > 전위형 후위형 차이 없음
let cnt = 0
cnt++
++cnt
console.log(cnt) // 2

// 값을 증가시킨 후 증가한 값을 바로 사용 > 전위형 증가 연산자
let prefix = 3
console.log(++prefix) // 4

// 값을 증가시키지만 기존값을 사용 > 후위형 증가 연산자
let postfix = 7
console.log(postfix++) // 7

 

다른 연산자 사이의 증가•감소 연산자

다른 대부분의 산술 연산자보다 순위가 높기 때문에 먼저 평가가 이뤄진다.

let prefix = 4
console.log(2 * ++prefix) // 10

let postfix = 5
console.log(10 / postfix--) // 2

기술적으로 문제는 없지만 한 줄에서 여러가지 일을 동시에 해서 가도성이 떨어진다.

코드를 읽을 때 눈을 수직으로 빠르게 움직이다 보면 cnt++ 같은 걸 놓치지 쉬우니까

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

 

비트 연산자 (bitwise operator)

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

- 비트 관련 연산자는 대부분 언어에서 지원한다.

 

비트 연산자 목록

1. 비트 AND ( & )

2. 비트 OR ( | )

3. 비트 XOR ( ^ )

4. 비트 NOT ( ~ )

5. 왼쪽 시프트(left shift) ( << )

6. 오른쪽 시프트 (right shift) (>> )

7. 부호 없는 오른쪽 시프트 (zero-fill right shift) ( >>> )

 

비트 연산자는 저수준(2진 표현)에서 숫자를 다뤄야 할 때 쓰이므로 흔하게 쓰이진 않는다.

웹 개발 시엔 이런 일이 자주 일어나지 않기 때문에 비트 연산자를 만날 일은 거의 없다.

그래도 암호를 다뤄야 할 땐 비트 연산자가 유용하기 때문에 필요할 때 비트 연산자 문서를 보는 걸 추천

 

쉼표 연산자 (comma operator)

- 좀처럼 보기 힘들고, 특이한 연산자 중 하나. 코드를 짧게 쓰려는 의도로 가끔 사용된다.

- 쉼표 연산자는 여러 표현식을 코드 한 줄에서 평가할 수 있게 해준다.

   이때 표현식이 각각 평가되지만 마지막 표현식의 결과만 반환된다.

let a = (1+2, 3+4)
console.log(a) // 7

1+2는 실행되지만 결과는 버려진다. 3+4만 a에 할당된다.

 

*쉼표의 우선순위는 매우 낮다

할당 연산자 = 보다 낮다. 위 예시에선 괄호가 중요한 역할을 한다.

괄호가 없으면 a = 1+2, 3+4에서 +가 먼저 수행되어 a = 3, 7이 되고

할당 연산자가 쉼표보다 높기 때문에 a= 3이 먼저 실행되고 7은 무시된다. 

 

마지막 표현식 외에 모든 것을 버리는 연산자는 어디서 사용될까!?

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

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

쉼표 연산자를 사용한 트릭은 여러 자바스크립트 프레임워크에서 볼 수 있다.

연산자의 사용 빈도가 높지 않지만 알아야 하는 이유!

쉼표 연산자는 코드 가독성에 도움이 되지 않으므로 곰곰이 생각해 본 후, 꼭 필요할 때만 사용하기!

 

총 정리 참고!

"" + 1 + 0 = "10"
"" - 1 + 0 = -1
true + false = 1
6 / "3" = 2
"2" * "3" = 6
4 + 5 + "px" = "9px"
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
"  -9  " + 5 = "  -9  5"
"  -9  " - 5 = -14
null + 1 = 1
undefined + 1 = NaN
" \t \n" - 2 = -2
Contents

포스팅 주소를 복사했습니다.

이 글이 도움이 되었다면 공감 부탁드립니다.