쫌만알자! (10) - 자바스크립트 연산자

Yeony (Nayeon Kim) · 2022-09-28

연산자(Operator)란?

연산자란 문장 부호 혹은 영어, 숫자로 구성된 예약된 구문입니다.

+라는 기호는 숫자를 추가하거나 문자열을 연결할 수 있게 하고, < 기호는 좌항과 우항의 값을 비교합니다.

이러한 연산자는 여러 종류로 분류할 수 있습니다.

산술 연산자 (Arithmetic Operator)

연산이라고 하면 가장 먼저 사칙연산이 떠오릅니다. 자바스크립트 또한 이런 산술적인 연산을 제공합니다. 사칙연산은 우리가 흔히 아는 기호(+, -, *, /)와 동일하게 움직입니다.

산술 연산자는 2가지로 나뉩니다.

이항 산술 연산자 (Binary Operator)

이항이라는 말은 항이 2개가 있다는 의미입니다. x + y는 연산되는 대상인 피연산자가 2개이죠? 그래서 이항(binary) 산술 연산자입니다.

연산자 동작
+ 덧셈
- 뺄셈
* 곱셈
/ 나눗셈
% 나머지

5 + 2 // 7 5 - 2 // 3 5 * 2 // 10 5 / 2 // 2.5 5 % 2 // 1

단항 산술 연산자 (Unary Operator)

이항 연산자와 달리 단항 산술 연산자는 1개의 피연산자만이 존재합니다.

조금 낯선 모양일 수 있습니다.

연산자 동작 부수효과
++ 증가 피연산자의 값을 변경
-- 감소 피연산자의 값을 변경
+ 숫자타입에는 효과없음.
숫자타입으로 변환될 수 있는 경우 변환된 값 반환
- 양수를 음수로, 음수를 양수로 반전 X
let x = 1 x++ // 2 x-- // 1 console.log(-x) // -1

여기서 증가/감소 연산자는 피연산자의 앞에 붙는지, 뒤에 붙는지에 따라 동작하는 시점에 차이가 있습니다.

let x = 10 let result // 선할당 후증가(postfix increment operator) result = x++ console.log(result, x) // 10, 11 // 선증가 후할당(prefix increment operator) result = ++x console.log(result, x) // 12 12 // 선할당 후감소(postfix decrement operator) result = x-- console.log(result, x) // 12 11 // 선감소 후할당(prefix decrement operator) result = --x console.log(result, x) // 10 10

조금 복잡하죠? 사실 저는 이런 증가/감소 단항 연산자는 잘 사용하지 않습니다. 잘못된 연산이 될 수도 있고, 처음 값을 할당한 변수의 값이 계속 바뀌기 때문이죠. 그래서 아래와 같은 방식을 추천합니다.

let x = 10 let result result = x + 1 console.log(result, x) // 11, 10 result = x - 1 console.log(result, x) // 10, 10

x의 값은 변하지 않고 result값만 계속 변화합니다. 만약 x가 내부적으로 계산되는 임시 변수가 아니라 함수의 인자 등으로 처음 넘겨받은 값이라면 변하지 않는 것이 더욱 좋을 것입니다.

문자열 연결 연산자

+ 연산자는 피연산자 중 문자열이 하나라도 존재할 때 문자열로 형변환하여 연결합니다.

1 + "1" // 11 1 + "1" + 1 + 0 // 1110 // true는 1로, false는 0으로 변환 1 + true // 2 1 + false // 1 // null은 0으로 변환 1 + null // 1 // undefined는 정의되지 않았기 때문에 // 숫자로 변환되지 않음 1 + undefined // NaN // 문자열에 + 붙이면 숫자타입으로 변환 1 + "1" // 2

할당 연산자 (Assignment Operator)

할당 연산자는 우항 피연산자의 평가 결과를 좌항 변수에 할당합니다.

연산자 동작 부수효과
= 할당 우항의 표현식 결과 값을 좌항의 변수에 할당
+= x = x + 2 "
-= x = x - 2 "
*= x = x * 2 "
/= x = x / 2 "
%= x = x % 2 "
let x = 3 x += 3 // 6 x -= 3 // 3 x *= 3 // 9 x /= 3 // 3 x %= 3 // 0

비교 연산자

비교 연산자는 좌항과 우항의 피연산자를 비교해 그 값을 불리언(true/false) 타입으로 반환합니다.

동등 비교 연산자 (Equality Operator)

값이 동등한 지를 평가하는 연산자입니다.

여기서 동등하다는 자바스크립트 엔진이 자체적으로 형변환을 한 후에 비교했을 때에 같다고 평가되었다는 의미입니다.
자바스크립트는 굉장히 자유로운 언어라고 했죠? 따라서 변수를 할당하면 자체적으로 타입을 추론합니다. 그리고 동등한지를 평가할 때 암묵적인 타입 변환을 합니다. 이런 형변환은 이따금 약간의 골칫거리가 되기도 하는데요. 형변환에 대해서는 추후 자세히 다룰 예정입니다. 지금은 자바스크립트가 타입을 추론해 바꾸기도 한다는 점만 알고 가기로 해요.

예시를 보겠습니다.

2 == 2 // true // 암묵적 타입 변환해 타입이 같을 경우에 2 == "2" // true

분명 숫자와 문자열을 비교했는데 두 값이 같다고 true를 반환하네요. 동등 비교가 타입을 바꿔서도 검사해주니 좋다고 생각할 수도 있지만, 사실 클린 코드를 작성하는 데에는 취약점입니다. 이미 우리는 앞서 타입 변환이 일어나 1 + '1'11이 되는 걸 확인했죠. 비슷한 예기치 못한 결과를 낳을 수 있기 때문에 일치 비교 연산자를 쓰는 것을 권장합니다.

일치 비교 연산자 (Strict Equality Operator)

일치 비교 연산자는 타입과 값이 모두 같을 경우에만 true를 반환합니다. 동등 비교보다 한층 강화된 연산자이기 때문에 엄격한 동등 연산자입니다.

2 === 2 // true 2 === "2" // false

일치 비교 연산자로 다 비교할 수 있으면 좋겠지만, 유의해야 할 값이 있습니다. 바로 NaN입니다.

NaN === NaN // false

MDN의 설명을 참고하면, NaN은 자신과 일치하지 않는 유일한 값입니다 (NaN is the only value that compares unequal to itself). 이건 일종의 버그에

따라서 isNaN()

부동등/불일치 비교 연산자 (Inequality / String Inequality Operator)

동등, 일치가 있다면 동등하지 않은 것과 불일치하는 것도 비교할 수 있어야겠죠?

자바스크립트에서는 ! 느낌표를 NOT 의미로 사용합니다.

1 != 5 // true 1 !== "1" // true

동등/일치 연산자에 !를 붙여주면, 부동등 연산자는 값이 같지 않을 때, 불일치 연산자는 값과 타입이 모두 같지 않을 때 true 값을 리턴합니다.

대소 비교 연산자

수학 연산에서 쓰이는 기호와 같습니다.

1 >= 2 // false 2 > 1 // true

삼항 연산자 (Ternary Operator)

삼항 연산자는 자바스크립트에서 유일하게 3개의 피연산자를 가지는 연산자입니다.

삼항 연산자는 조건식의 평가에 따라 반환되는 값이 달라집니다.

삼항 연산자를 세 부분으로 나누어 살펴보겠습니다.

삼항연산자

? 전까지는 조건식이 들어갑니다. 조건식의 결과는 Boolean 타입으로 평가되고, 만약 Boolean 타입이 아니라면 암묵적인 형변환을 통해 그 값을 Boolean으로 변환합니다.

만약 조건식이 true라면 ? 뒤의 값이, false라면 : 뒤의 값이 삼항연산자의 값으로 평가됩니다.

function isAdult(age) { return age > 19 ? "You are an adult!" : "You are too young..." } isAdult(15) // 'You are too young...' isAdult(24) // You are an adult!

삼항 연산자는 if...else문과 비슷하다고 생각할 수 있는데요. 유의해야 할 차이점이 있습니다. if...else조건문이고, 삼항 연산자는 표현식이란 점입니다.

이전 글에서 값, 식, 문의 차이를 알아보며 문은 변수에 할당할 수 없지만, 표현식은 값으로 평가되어 할당할 수 있다고 설명한 바가 있습니다. 따라서 값처럼 사용할 수 있는 삼항 연산자는 무척 유용합니다.



논리 연산자 (Logical Operator)

논리 연산자는 우항과 좌항의 피연산자를 논리적으로 연산합니다.

논리적으로 연산한다는 말이 조금 어렵게 느껴집니다. 간단하게 Boolean 연산이라고 생각하면 됩니다. 논리연산은 truefalse만 존재하는 연산입니다.

연산자 동작 의미
|| 논리합(OR) 피연산자 중 하나라도 true이면 true
&& 논리곱(AND) 피연산자 모두 true여야 true
! 논리부정(NOT) 피연산자의 값을 반전한 값 반환

이렇게만 봐서는 좀 어렵습니다. 예제를 함께 살펴보겠습니다.

// 논리합 (||) true || true // true true || false // true false || true // true false || false // false // 논리곱(&&) true && true // true true && false // false false && true // false false && false // false // 부정 (!) !true // false !false // true

논리 부정 연산자(!)는 항상 Boolean값으로 반환되는데, 피연산자의 값이 Boolean이 아니면 Boolean 값으로 암묵적 형변환하여 평가합니다.

console.log(!0) // true console.log(!"Any String") // false

논리 곱 연산자(&&)는 늘 2개의 피연산자 중 하나로 평가됩니다.

console.log("Apple" && "Banana") // Banana

typeof

typeof 연산자는 이름에서 알 수 있듯 피연산자의 타입을 문자열로 반환합니다.

typeof 연산자가 반환하는 값의 종류는 다음과 같습니다.

  • string
  • number
  • boolean
  • undefined
  • symbol
  • object
  • function

사실 typeof 로 검사해도 우리가 원하는 타입과 정확히 맞아떨어지는 결과가 반환되지만은 않습니다.

typeof "" // string (null 예상) typeof NaN // number typeof null // object typeof [] // object typeof new Date() // object

조금 이상하죠? 특히 null을 검사했는데 object로 넘기는 건 정말 이상합니다. 이건 자바스크립트의 버그입니다. 하지만 기존에 이미 작성된 코드와의 호환을 위해 의도적으로 남긴 버그입니다.

따라서 null을 체크할 때에는 ===일치 연산자를 사용하는 것이 좋습니다.

ES6 이후 자바스크립트 스펙에서 추가된 연산자들은 추후 알아보도록 하겠습니다.

다음 글에서는 제어문에 대해 알아보겠습니다.

값, 식, 문 👈 이전 글 보기
제어문(1) - 조건문 👈 다음 글 보기


쫌만알자
Loading script...
© 2022 Nayeon Yeony Kim