본문 바로가기

연산자(Operators) | JS & ES6 공부 노트 #6

기술적인 이야기/웹 개발 2019. 8. 21.
반응형

연산자의 정의를 어디까지 볼 것인가에 대한 객관적인 기준은 없는 것 같습니다. 이 노트에서는 연산자의 범위를 대체로 '영단어가 아닌 문자' 중에서만 발췌합니다. 그리고 연산자 하나하나의 기능을 살펴보기보다는 그저 훑고 지나가는 수준으로만 정리합니다. 불성실한(?) 글 미리 죄송하다는 말씀드립니다. 😏

유명한 연산자들

굳이 설명이 필요 없을 것 같은 연산자들도 많은 것 같습니다. 왜냐하면 대부분의 언어에서 거의 동일하게 사용되기 때문이지요.

대표적으로 다음과 같은 산술 연산자들이 있습니다.

+ - * /

곱하기(*)와 나누기(/)는 교과과정의 산수나 수학에서 쓰이는 기호와는 좀 다른데, 오히려 프로그래밍 언어에서는 이 두 연산자가 더 유명하므로 굳이 설득(?) 하지 않아도 될 것 같습니다.

그리고 + 연산자는 숫자 타입(Numbers)의 경우 덧셈으로 작용하지만 문자열(String)의 경우 이어 붙이기로 동작한다는 특징도 있습니다. 이도 최근 몇몇 언어에서 비슷하게 지원하기 때문에 나름 익숙한 연산자 같습니다.

비트 연산자(bitwise operators)도 거의 비슷합니다.

& | ^ ~ >> >>> <<

다만 여기서 >>> 연산자는 좀 특수한데 부호 없는 시프트 연산자입니다. 쓸 일이 얼마나 있을지는 모르겠지만요.

대입 연산자 = 도 유명합니다. 요즘은 오해하시는 분은 적겠지만, 이 연산자는 대입 혹은 할당(assignment) 연산자이지 비교 시의 동등(equal, ==)을 의미하는 연산자가 아닙니다.

이 대입 연산자는 각종 산술 연산자와 결합되어 여러 방식으로 활용될 수 있는 점도 거의 비슷합니다.

+= -= *= /= &= |= ^= >>= >>>= <<=

앞서 = 연산자는 비교가 아니라고 했는데, 이제 논리 비교 용도로 사용할 수 있는 연산자도 살펴봅시다.

== != > < >= <= && || !

역시 다른 대다수의 언어와도 비슷합니다.

정말요?

비슷하긴 하지만 차이가 있는 부분도 있습니다. 자바스크립트의 비교 연산자는 타입을 매칭 시키지 않고 데이터를 비교하는 연산자인데 간혹 이상한 결과를 내놓기도 해서 자바스크립트의 악명 높은(?) 특징 중 하나입니다. 예를 들자면 문자열 100과 숫자 100을 동일하다고 하는 등 말이죠. 이 내용은 아래 === 연산자 소개 글에서 계속 이어집니다.

다음으로, 특수한 연산자로 ?가 있는데 C에서 쓰이는 그 물음표와 유사한 용도입니다.

condition ? trueValue : falseValue

condition이 참이면 trueValue를, 거짓이면 falseValue를 전달시키는 역시 유명한 연산자입니다. 자바스크립트가 C 언어에 얼마나 영향을 많이 받았는지 알 수 있는 구문이기도 합니다.

특수한 연산자들

Javascript 혹은 ES6의 좀 유니크해 보이는 연산자를 살펴봅시다.

===

앞서 동일한지를 비교하기 위한 == 연산자는 좀 특이하게도 타입을 신경 안 쓰는 비교 연산자라 했었는데, 다른 언어의 비교 연산자와 비슷한 연산자 역시 제공됩니다. 바로 === 연산자입니다.

'100' == 100     // true
'100' === 100    // false
'100' != 100     // false
'100' !== 100    // true

=== 연산자를 이용하면 타입과 데이터가 완벽하게 매칭 하는지를 비교합니다. 비슷하게 !== 연산자는 완벽하게 일치하지 않는지를 검사하는 연산자입니다.

따라서 다른 언어에 익숙한 채로 자바스크립트에서 제어문을 작성해야 한다면 == 보다는 ===를 쓰도록 습관화하는 편이 좋을 것 같습니다. 🤪

in

in 키워드는 이 노트에서 연산자로 보지 않으려 했던 명령어지만 좀 특이하기에 메모합니다.

일부 언어에서 이 in 키워드는 열거(interation)형 루프 혹은 특정 컬렉션의 아이템 존재 유무를 테스트하는 용도로 사용되는 경우가 많습니다. 제 개인적인 경험으로 Python이나 Swift가 이에 해당합니다.

하지만 Javascript나 ES6에서 in 키워드는 의미가 좀 다릅니다. 이 키워드는 특정 인스턴스나 오브젝트의 프로퍼티가 존재하는지를 평가하는 특수한 용도로 사용됩니다.

단순한 예로 아래를 살펴봅시다.

1 in ['one', 'two', 'three']           // true
'one' in ['one', 'two', 'three']       // false
'length' in ['one', 'two', 'three']    // true

이 중에도 모두 이해가 된다면 이미 이 요상한(?) 언어에 익숙하다는 의미일지도 모릅니다. 하지만 이해가 안 된다면 다른 언어에 이미 익숙한 상태라고 봐야겠지요.

  1. 해당 배열(Array)은 3개의 아이템이 있으면 이 중 1번 인덱스가 존재하기 때문에 true입니다.
  2. 배열(Array)에는 one이라는 프로퍼티가 없기 때문에 false입니다.
  3. 배열(Array)에는 length라는 프로퍼티가 있기 때문에 true입니다.

이해가 되시나요?

다른 예를 하나 봅시다.

'one' in {'one': 1, 'two': 2, 'three': 3}      // true

사전형(Dictionary)은 특이하게도 키 이름이 프로퍼티로 동작합니다. 그래서 배열(Array)과는 다른 결과가 돌아옵니다.

Spread와 Rest

스프레드 연산자(...)는 ES6에서 추가된 특수한 연산자입니다. 이름대로 컬렉션을 전개한다, 확산한다, 펼친다는 등의 의미로 사용됩니다.

대표적인 예로 배열 이어 붙이기가 있습니다.

let arr = [1, 2, 3]
let arr2 = [...arr, 4, 5, 6]

위 코드를 실행시키면 arr2에는 [1, 2, 3, 4, 5, 6]이라는 배열이 들어가 있습니다.

이런 식으로 오브젝트의 내용을 마치 코드로 풀어내버리는 듯한 효과를 내는 연산자가 바로 이 스프레드 연산자입니다. 이 외에도 활용처는 많이 있겠지만 일단 다른 예제는 생략합니다. 추후 기회가 있다면 별도로 정리해 보겠습니다.

여담으로 ...은 함수 인자 정의에서 사용되면 Rest 연산자로 동작하게 됩니다.

function anotherFunc(value, ...rest) {
    console.log(value);
    console.log(rest);
}

anotherFunc(1, 2, 3, 4, 5)

위 코드를 실행시키면 콘솔에 1이 우선 표시되고 그다음에 [2, 3, 4, 5]가 출력됩니다. 즉, 1번째 value 인자(argument)가 먼저 들어오고 그다음은 ...으로 나머지 모든 인자가 정의되게 됩니다.

마무리

이번 글은 훑어보기만 하고 끝내려고 했는데 쓰다 보니 이상한 데(?)서 글의 양이 확 늘어나버린 것 같습니다. 어쨌거나 연산자 훑어보기 편은 여기서 마칩니다.

728x90
반응형

댓글