연산자는 하나 이상의 표현식을 대상으로 산술,할당,비교,논리,타입,지수연산 등을 수행하여 하나의 값을 만든다. 이 과정에서 연산의 대상을 피연산자라고 하며 피연산자는 값으로 평가될 수 있는 표현식이어야한다.
산술 연산자
피연산자를 대상으로 수학적 계산을 진행하는 연산자로 연산이 불가능하면 NaN을 반환하는 것이 특징이다.
산술연산을 진행하면 항상 새로운 값을 만들게 된다.
종류로는 +,-,*,/,% 다섯가지가 존재한다.
단항 산술 연산자
1개의 피연산자를 가지는 산술연산자들을 의미한다.
산술연산자와 다르게 피연산자의 값을 변경하는 기능을 가진다.
+ 연산자는 숫자타입에 적용할대 어떠한 부수효과도 없다. 단 숫자가 아닌 연산자에 활용하면 숫자 타입으로 반환해준다.
var x = '1';
console.log(+x); //1 as number
//부수효과 없음
console.log(x); // "1" as string
x = true;
console.log( +x ); // 1 as number
console.log(+x+1); // 2 as number. true는 숫자와 연산시 숫자 1로 치환된다.
//부수효과 없음
console.log(x); // true
x = false;
console.log( +x ); // 0 as number
console.log(+x+1); // 1 as number. false는 숫자와 연산시 숫자 0으로 치환된다.
//부수효과 없음
console.log(x); // false
x = 'x';
console.log(+x); // NaN
//부수효과 없음
console.log(x); //'x'
+ 연산자를 피연산자 2개에 사용하고 피연산자 중 하나 이상이 문자열이라면 문자열 연결 연산자로 동작하게 된다. 예시를 보면 이해가 바로 될 것이다.
//피연산자 중 하나 이상이 문자열인 경우
"1"+2; // '12' as string
1 + '2'; // 12 as string
// 피연산자 중 하나 이상이 문자열인 경우 외의 경우
1 + 2; // 3
1 + true; // 2
1+ false; // 1
1 + null; // 1. null 또한 산술 연산자로 작동한 연산식에서는 0으로 치환된다.
1 + undefined; // NaN
+undefined; // NaN
1 + true
위 예시를 조금 더 보자. 개발자의 의도와 상관없이 JS엔진은 숫자타입으로 형을 변환하기도 한다. 이를 암묵적 타입 변환 혹은 타입 강제변환이라고 한다.
해당 내용도 나중에 자세히 알아보자.
할당 연산자
우항의 피연산자 평가 결과를 좌항의 변수에 할당하는 역할을 해준다.
이전 챕터에서 표현식은 값으로 평가되는 문이라고 했으며 문에는 표현식과 표현식이 아닌 문이 있다고 했다. 그러하면 할당문은 표현식일까?
이전 글에서 표현식과 표현식이 아닌 문을 판단하는 쉬운 방법은 console.log() 에 넣어보는 것이라고 했다. 아래 예제를 한번 넣어보자.
var x;
console.log(x=10);
// 10
놀랍게도 할당문은 값으로 평가되는 표현식으로 동작함을 알 수 있다. 이러한 특징한다면 변수들에 동일한 값을 연쇄 할당하는 것도 가능하다.
var a, b, c;
a = b = c = 10;
console.log(a, b, c)
// 10, 10, 10
비교 연산자
비교 연산자는 좌항과 우항을 비교한 다음 그 결과를 불리언 값으로 변환한다.
보통 if,for 문등에서 많이 사용되게 된다.
JS의 경우 좌항과 우항을 비교할 때 먼저 암묵적 타입변환을 통해서 타입을 일치 시킨 후 같은값인지 평가한다.
5 ==5; // true
5 == '5'; // true
이러한 JS의 속성은 편리한 경우도 있지만 결과를 예측하기 어렵고 실수하기가 쉽다. 아래 예시를 보자.
'0' == ''; // false
0 == ''; // true
0 == '0'; // true
false == 'false'; // false
false == '0'; // true
false == 0; // true
false == null; // false
null == 0; // false*
false == undefined; //false
이러한 문제때문에 동등비교(==) 연산자보다 일치 비교(===) 연산자를 사용하는 것이 더 좋다.
일치 비교 연산자는 좌,우항의 타입과 값을 모두 비교하기때문에 결과의 예측이 쉽다.
5 ===5; // true
5 ==='5'; // false
일치 비교 연산자를 활용할 때 NaN을 주의하자.
NaN === NaN; // false
'1' == NaN; // false
NaN은 자신과도 일치하지 않는다. 따라서 숫자가 NaN인지 확인하기 위해서는 Number.isNaN 함수를 활용해야 한다.
Number.isNaN(NaN); // true
Number.isNaN(10); // false
Number.isNaN(1 + undefined); // true
추가적으로 말하자면 0도 주의해야한다. 놀랍게도 JS에는 양의 0과 음의0이 존재한다. 이들을 비교하면 true를 반환하게 된다!
0 === -0; // true
0 == -0; // true
0 === -0; // true
Object.is(-0, +0); // false
NaN === NaN; // false
Object.is(NaN, NaN); // true
Object.is 함수를 이용하면 좀 더 예측 가능한 정확한 비교가 가능하니 알아두자.
대소 관계 비교 연산자
피연산자의 피교를 비교해서 불리언 값을 반환한다.
상항 조건 연산자
삼항 연산자의 사용은 아래와 같다.
var x = 2, result;
if (x%2) result = '홀수';
else result = '짝수';
var result = x % 2 ?'홀수' : '짝수';
자세히 보면 삼항연산자의 경우 if...else 문고 ㅏ상당히 유사한것을 알 수 있다.
두 방식의 차이는 삼항조건 연산자 표현식은 값처럼 사용할 수 있지만 if...else 문은 값으로 사용할 수 없다는 점이다.
삼항조건 연산자 표현식은 값으로 평가할 수 있는 표현식이기 때문에 조건에따라서 값을 결정해야 할때 삼항 조건 표현식을 사용하는게 더 좋을 수 있다.
단, 조건들이 여러개라면 if...else문의 가독성이 훨씬 좋아지니 참고하자.
논리 연산자
연산자 파트의 주의점은 연산자의 피연산자가 굳이 불리언값이 올 필요가 없다는 점이다. 만약 불리언이 아닌 값이 피연산자로 들어오면 불리언 타입으로 암묵적 변환 이후 계산이 수행된다.
AND(&&) 나 OR(||)같은 경우 표현식의 평가 결과가 불리언 값이 아닐 수 있음을 생각하자.
'Cat' && 'DOG'; // 'DOG'
두 표현식은 2개의 피연산자 중 하나의 값으로 평가된다. 위 연산에서 Cat이 참인 형태이기에 연산이 끝까지 수행되며 'DOG' 값을 가진다고 이해하면 편하다.
쉼표 연산자
쉼표 연산자는 왼쪽 피연산자부터 차례대로 피연산자를 평가하면 평가가 끝나면 마지막 피연산자의 평가 결과를 반환하게 된다.
var x, y, z;
x = 1, y=2, z=3; // 3
그룹 연산자
사칙연산과 같이 연산자간 우선순위를 바꿔줄 수 있다.
10 *2 +3; // 23
10 * (2 +3); // 50
typeof 연산자
신기하게 JS에서 typeof는 함수가 아닌 연산자 처리다. 피연산자의 데이터 타입을 문자열로 반환해준다.
typeof ''; // "string"
typeof 1; // "number"
typeof NaN; // "number"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof Symbol(); // "symbol"
typeof null; // "object"
typeof []; // "object"
typeof {}; // "object"
typeof new Date(); // "object"
typeof /test/gi; // "object"
typeof function() {}; // "function"
지수 연산자
ES7에서 도입된 연산자로 Math.pow 메서드보다 더 가독성좋게 지수계산을 표현할 수 있다.
2 ** 2; // 4
2 ** 0; // 0
//지수연산자 도입전
Math.pow(2, 2); // 4
Math.pow(2, 0); // 0
음수를 활용하는 경우 괄호로 묶어야 함을 주의하자
-5 ** 2 // SyntaxError: ...
(-5) ** 2 // 25
그 외에도 여러가지 연산자들이 존재하지만 이는 나중에 알아보자.
연산자 우선순위
연산자 우선순위란 여러개의 연사자로 이뤄진 문이 실행될 때 연산자가 실행되는 순서이다.
'FrontEnd > Deep Dive' 카테고리의 다른 글
[JS] DeepDive(9) 타입 변환과 단축 평가 (0) | 2023.07.26 |
---|---|
[JS] DeepDive(8) 제어문 (0) | 2023.07.22 |
[JS] DeepDive(6) 데이터 타입 (0) | 2023.07.21 |
[JS] DeepDive(5) 표현식과 문 (0) | 2023.07.19 |
[JS] DeepDive(4) 변수 (0) | 2023.07.18 |