JS 연산자 : 산술, 비교, 논리, 대입
1. 산술 연산자
산술 연산자의 종류
1️⃣ + : 더하기 연산자
2️⃣ - : 빼기 연산자
3️⃣ * : 곱하기 연산자
4️⃣ ** : 제곱 연산자(ES6)
5️⃣ / : 나누기 연산자
6️⃣ % : 나머지 연산자
7️⃣ ++ : 증가 연산자(+1)
8️⃣ -- : 감소 연산자(-1)
산술 연산자의 피연산자는 숫자 타입이다.
때문에 산술 연산자의 피연산자로 숫자 타입이 아닌 데이터 타입을 사용하고자 하면, 묵시적 형변환이 일어난다.
boolean 타입 👉 number 타입
1️⃣ true : 1
2️⃣ false : 0
string 타입 👉 number 타입
1️⃣ ''(빈문자열) : 0
2️⃣ '1234' : 1234
3️⃣ '가나다' : NaN
📌 문자열 타입 결합
문자열 타입은 산술 연사자 중 더하기 연산자를 사용하여 연산을 시도하려고 할 때에 숫자 타입으로 형변환이 일어나지 않고 문자열 결합이 일어난다.
예를 들어 다음과 같은 문자열이 있다고 해보자.
<script>
var str = '1234';
var result = str + 1;
</script>
이러한 경우 일반적인 산술 연산자는 피연산자를 숫자로 인식하기 위하여 묵시적 형변환을 적용할 것이고,
변수 str 는 문자열 '1234' 가 아닌 숫자 타입 1234 로 변경하여 산술 연산을 적용하고자 할 것이다.
하지만 더하기 연산자는 문자열의 경우 특수하게 반응하여 문자열 그대로 결합하게 된다.
그렇다면 타입은 어떻게 될까?
문자열 결합이 되기 때문에 타입 또한 숫자가 아닌 문자열이 된 것을 확인할 수 있다.
만약 위의 코드를 아래와 같이 변경하게 되면 어떻게 될까?
<script>
var str = '1234';
var result = str - 1;
</script>
더하기 연산자를 빼기 연산자로 바꾸어 적용해보니, 산술 연산자의 영향으로 문자열 타입이 숫자 타입으로 변하여 숫자 연산이 적용된 것을 확인할 수 있다.
📌 문자열과 불린 타입의 산술 연산의 적용
<script>
var a = '';
var b = true;
var result = a - b;
console.log(result);
console.log(typeof result);
</script>
위와 같이 적용하였을 때에 result 의 값은 어떻게 도출될 수 있을까?
결과는 -1 이 나왔는데, 왜 이러한 결과가 나온 것일까?
먼저 변수 a 에 할당된 값은 빈문자열이다.
빈문자열은 숫자 타입으로 형변환이 되면 0 으로 처리된다.
변수 b 는 불린 타입의 값 true 이다.
true 는 숫자 타입으로 형변환 되면 1 이 된다.
때문에 변수 result 에 할당된 식은 0 - 1 이 되기 때문에 최종적으로 -1 이 결과값이 나온 것이다.
📌 숫자 타입으로의 명시적 형변환
- 0
* 1
/ 1
자바스크립트에서는 묵시적 형변환을 자동으로 지원하고 있기 때문에 간혹 어느 부분에서 무슨 형변환이 일어나고 있는지 확인하기 어려울 수 있다.
때문에 숫자 타입이 아닌 데이터 타입의 값에 대한 변화 없이 타입만 바꿔주는 것으로 타입 변화를 눈으로 확인하기 수월해 질 수 있다.
📌 NaN , infinity 란?
NaN 은 not a number 라는 뜻으로, 숫자가 아니라는 의미이다.
앞서 문자열 타입이었던 '가나다' 를 숫자 타입으로 연산하려고 하였을 때 결과가 NaN 인 이유가 바로 가나다 는 숫자로 환산할 수 없기 때문이다.
다만 '1234' 의 경우에는 해당 값을 숫자 타입 1234 로 바꿀 수 있기 때문에 이러한 경우에는 NaN 이 출력되지 않는다.
infinity 는 무한대를 나타내며 숫자이기는 하지만 정의되지 않았기 때문에 나타나는 것이다.
NaN 은 undefined 타입처럼 값을 비교할 수 없기 때문에 NaN == NaN 과 같은 연산이 적용되지 않는다.
대신 isNaN() 이라는 함수가 존재하는데, 이 함수를 통해 숫자 타입인지 NaN 인지를 알 수 있어 조건문에서 활용 가능하다.
또한 infinity 도 isFinite() 함수가 존재하는데, 무한수이면 false 를 반환하고, 유한수이면 true 를 반환한다.
하지만 infinity 는 비교 연산도 가능하기 때문에 isNaN() 함수에 비하여 활용 빈도가 적다.
2. 비교 연산자
비교 연산자의 종류
- 동치 비교 연산자
1️⃣ == : 일치하는가?
2️⃣ === : 일치하는가? (type 일치 여부까지)
3️⃣ != : 일치하지 않는가?
4️⃣ !== : 일치하지 않는가? (type 불일치 여부까지)
- 대소 비교 연산자
5️⃣ > : 더 큰가?
6️⃣ < : 더 작은가?
7️⃣ >= : 더 크거나 같은가?
8️⃣ <= : 더 작거나 같은가?
비교 연산자는 큰 틀에서 동치 비교와 대소 비교로 종류를 나눌 수 있다.
동치 비교의 피연산자는 문자열, 불린, 숫자 타입 모두를 비교할 수 있지만,
대소 비교의 피연산자는 숫자 타입으로 비교하기 때문에 다른 타입이 오면 숫자로 변환하게 된다.
또한 결과는 모두 불린 타입의 값인 true 또는 false 로 나온다.
📌 == 와 === 의 차이
== 는 단순히 값을 비교하기 때문에 서로 다른 타입에서의 비교에서도 같은 타입으로 묵시적 형변환을 하여 비교하게 된다.
하지만 === 의 경우에는 타입도 일치하는지를 묻기 때문에 == 와 다른 결과를 볼 수 있다.
<script>
var a = '가나다';
var b = new String('가나다');
var c = new String('가나다');
console.log(a == b);
console.log(a === b);
console.log(a == c);
console.log(a === c);
console.log(b == c);
console.log(b === c);
</script>
변수 a 는 문자열 타입, 변수 b 는 객체 타입, 변수 c 또한 객체 타입이다.
때문에 a == b 는 true 를 볼 수 있었지만, a === b 는 서로의 데이터 타입이 다르기 때문에 false 라는 결과가 나온 것이다.
이는 a 와 c 의 비교에서도 마찬가지 결과를 얻을 수 있었음을 쉽게 확인할 수 있다.
하지만 결과에서 이상한 점이 보인다.
b 와 c 는 값도 '가나다' 로 동일하고, 데이터 타입도 객체 타입으로 동일하기 때문에 == 과 === 비교 모두 true 를 얻을 수 있을 것이라고 기대하였지만, 모두 false 라는 결과를 보았다.
왜 이같은 결과를 얻게 된 것일까?
이는 바로 b 와 c 가 객체 타입이기 때문이다.
서로의 타입이 다를 경우에서의 == 비교는 객체의 내부의 값을 단순 비교 할 수 있도록 하지만,
비교하려는 대상이 같다면 내부의 값을 비교하려고 하지 않고, 객체의 주소값을 비교하려고 한다.
때문에 b 와 c 는 값이 아닌 서로의 객제 주소값을 비교하려고 하여 값이 다르다는 false 결과를 보여준 것이다.
그렇다면 b 와 c 를 비교하기 위해서는 어떻게 해야 할까?
다양한 방법이 있지만 간단한 비교를 위해서는 JSON.stringify() 함수를 활용할 수 있다.
JSON.stringify(b) === JSON.stringify(c)
JSON.stringify 함수는 객체 전체를 JSON 문자열화하여 객체 자체를 비교할 수 있게 된 것이다.
3. 논리 연산자
논리 연산자 종류
1️⃣ && : and 연산자
2️⃣ || : or 연산자
3️⃣ ! : 부정 연산자
논리 연산자는 기본적으로 자바와 쓰임새가 유사하다.
피연산자로는 불린 타입을 반환할 수 있는 경우 활용이 가능하기 때문에 해당 연산자에서 또한 다른 타입에 대한 묵시적 형변환이 일어나기도 한다.
예시를 살펴보자.
true && 0
이러한 경우에는 결과가 어떻게 나올까?
위 예시의 결과는 0 이 나온다.
왜 이런 결과가 나온 것일까.
자바스크립트에서의 논리 연산자는 약식으로 활용이 가능한데, 바로 이러한 특징을 이용한 예시인 것이다.
&& 연산자를 사용하게 되면 false 를 만날 때 해당 데이터를 반환하게 되고,
|| 연산자를 사용하게 되면 true 를 만날 때에 해당 데이터를 반환하게 된다.
두 연산자 모두 목적하는 값을 만나지 못 할 때에는 가장 오른쪽에 위치한 마지막 항의 내용이 반환된다.
이를 바탕으로 위의 내용에 대해 더 설명해 보자면, 숫자 타입의 0 은 불린 타입으로 false 이기 때문에 0 이 반환된 것이다.
몇 가지 예시를 더 살펴보자.
📌 각 타입에서의 false
문자열 타입에서의 false 👉 '' 빈문자열
숫자 타입에서의 false 👉 0 또는 NaN
📌 각 타입에서의 0
문자열 타입에서의 0 👉 '' 빈문자열
불린 타입에서의 0 👉 false
4. 대입 연산자
대입 연산자는 = 으로 연산자 오른편에 있는 리터럴 등을 연산자 왼편의 변수에 값을 할당하게 한다.
이 자체로도 가장 많은 활용을 하지만, 다른 연산자와 함께 단항 연산자로 활용하기도 한다.
대입 연산자의 종류
- 산술 연산자와의 결합
1️⃣ += : x += y , x = x + y
2️⃣ -= : x -= y , x = x - y
3️⃣ *= : x *= y , x = x * y
4️⃣ /= : x /= y , x = x / y
5️⃣ %= : x %= y , x = x % y
6️⃣ **= : x **= y , x = x ** y
- 비트 연산자와의 결합
1️⃣ <<= : x <<= y , x = x << y
2️⃣ >>= : x >>= y , x = x >> y
3️⃣ >>>= : x >>>= y , x = x >>> y
4️⃣ &= : x &= y , x = x & y
5️⃣ ^= : x ^= y , x = x ^ y
6️⃣ |= : x |= y , x = x | y
대입 연산자를 통해 변수에 값을 할당하지 않고 선언만 하게 되었을 때에는 해당 변수의 타입을 지정할 수 없기 때문에 undefined 타입이 된다.