JS

JS 연산자 : 산술, 비교, 논리, 대입

mukom 2022. 11. 11. 19:13

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 타입이 된다.