[모던 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
'Study > JavaScript' 카테고리의 다른 글
class 방식, extends, constructor (0) | 2023.06.13 |
---|---|
[모던 JavaScript] 코어 자바스크립트 - 자바스크립트 기본 - 7. 형 변환 (0) | 2023.05.19 |
[모던 JavaScript] 코어 자바스크립트 - 자바스크립트 기본 - 6. alert, prompt, confirm을 이용한 상호작용 (0) | 2023.03.15 |
[모던 JavaScript] 코어 자바스크립트 - 자바스크립트 기본 - 5. 자료형 (0) | 2023.03.08 |
[모던 JavaScript] 코어 자바스크립트 - 자바스크립트 기본 - 4. 변수와 상수 (0) | 2023.02.23 |
소중한 공감 감사합니다.