연산자는 하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입, 지수 연산을 수행해 하나의 값을 만든다.
이때 연산의 대상자를 피연산자라고 한다. 피연산자는 값으로 평가될 수 있는 표현식 이어야 한다.
// 산술 연산자
5 + 4 // 20
// 문자열 연결 연산자
'My name is ' + 'Song' // My name is Song
// 할당 연산자
color = 'red' // 'red'
// 비교 연산자
3 > 5 // false
// 논리 연산자
true && false // false
// 타입 연산자
typeof 'Hi' // string
피연산자가 값 이라는 명사의 역할을 한다면 연산자는 피연산자를 연산하여 새로운 값을 만든다는 동사의 역할을 한다고 볼 수 있다. 다시 말해, 피연산자
는 연산의 대상이 되어야 하므로 값으로 평가할 수 있어야한다.
산술 연산자
산술 연산자는 피연산자를 대상으로 수학적 계산을 수행해 새로운 숫자 값을 만든다.
연산이 불가능 할 경우 NaN의 값을 반환한다.
산술 연산자는 피연산자의 개수에 따라 이상 산술 연산자와 단항 산술 연산자로 구분할 수 있다.
이항 산술 연산자
이항 산술 연산자는 2개의 피연산자를 산술 연산하여 숫자 값을 만든다.
연산자 설명 예시 결과 + 덧셈 5 + 2 7 - 뺄셈 5 - 2 3 * 곱셈 5 * 2 10 / 나눗셈 5 / 2 2.5 % 나머지 5 % 2 1 ** 거듭제곱 5 ** 2 25 다항 산술 연산자
단항 산술연산자는 1개의 피연산자를 산술 연산하여 숫자 값을 만든다.
연산자 설명 예시 결과 ++ 증가 연산자. 피연산자의 값을 1 증가시킵니다. let a = 1; a++; 2 -- 감소 연산자. 피연산자의 값을 1 감소시킵니다. let a = 2; a--; 1 + 단항 플러스. 피연산자의 값을 숫자로 변환합니다. let a = "5"; +a; 5 - 단항 마이너스. 피연산자의 부호를 반전시킵니다. let a = 5; -a; -5
주의할 점은 이항 산술 연산자와는 달리 증가/감소 연산자는 피연산자의 값을 변경하는 부수효과가 있다는 것이다.
즉, 증가/감소 연산을 할면 피연산자의 값을 변경하는 암묵적 할당이 발생한다.
ex)
var x = 1;
x++; // x = x + 1
console.log(x) // 2
x--; // x = x - 1
console.log(x) // 1
증가/감소 연산자는 위치에 의미가 있다.
피연산자 앞에 위치한 전위 증가/ 감소연산자 는 먼저 피연산자의 값을 증가/감소 시킨 후, 연산을 수행한다.
피연산자 뒤에 위치한 후위 증가/감소 연산자는 먼저 다른 연산을 수행한 후 , 피연산자의 값을 증가/감소 시킨다.
var x = 5, result; result = x++; console.log(result, x) // 5, 6 result = ++x; console.log(result, x) // 6, 6
단항 연산자는 피연산자에 어떠한 효과도 없다. 음수를 양수로 반전하지도 않는다.
// 아무런 효과가 없다 +10 // 10 +(-10) // -10
숫자 타입이 아닌 피연산자에 + 단항 연산자를 사용하면 피연산자를 숫자 타입으로 변환하여 반환한다.
이때 피연산자를 변경하는 것이 아니고 숫자 타입으로 반환한 값을 생성해 반환하기 때문에 부수효과가 없다.
- 연산자도 마찬가지 피연산자의 부호를 반전한 값을 반환한다. 이때 피연산자를 변경하는 것이 아니고 부호를 반전한 값을 생성해 반환한다.
문자열 연결 연산자
연산자는 피연산자 중 하나 이상이 문자열인 경우 연결 연산자로 동작한다.
// 문자열 연결 연산자 '1' + 2; // '12' // 산술 연산자 1 + 2 // 3 // true는 1로 타입 변환한다. true + 1 // 2 // false는 0로 타입 변환한다. false + 1 // 1 // null은 0으로 타입 변환한다. 1 + null // 1 // undefined는 숫자로 타입 변환되지 않는다. +undefined // NaN
위의 예제에서 알아야 할 것은 개발자의 의도와 상관없이 자바스크립트 엔진에서 암묵적으로 타입을 변환해서 계산하기도 한다는 것이다.
1 + true 를 연산하면 자바스크립트 엔진에서는 true를 1로 계산해 값을 반환하는데 ,
이를
암묵적 타입 변환
또는타입 강제 변환
이라고 한다.
할당연산자
할당 연산자는 우항에 있는 피연산자의 평과 결과를 좌항에 있는 변수에 할당한다.
할당 연산자는 좌항의 변수에 값을 할당하기 때문에 변수가 변하는 부수효과가 있다.
할당 연산자 | 동일 표현 예시 | 부수 효과 설명 |
---|---|---|
= | a = b | 변수 a에 b의 값을 할당합니다. 이 과정에서 a의 원래 값이 변경됩니다. |
+= | a += b는 a = a + b와 동일 | a와 b의 합을 a에 할당합니다. a의 값이 변경됩니다. |
-= | a -= b는 a = a - b와 동일 | a에서 b를 뺀 결과를 a에 할당합니다. a의 값이 변경됩니다. |
*= | a *= b는 a = a * b와 동일 | a와 b의 곱을 a에 할당합니다. a의 값이 변경됩니다. |
/= | a /= b는 a = a / b와 동일 | a를 b로 나눈 결과를 a에 할당합니다. a의 값이 변경됩니다. |
%= | a %= b는 a = a % b와 동일 | a를 b로 나눈 나머지를 a에 할당합니다. a의 값이 변경됩니다. |
**= | a *= b는 a = a * b와 동일 | a의 b 제곱 결과를 a에 할당합니다. a의 값이 변경됩니다. |
표현식은 값으로 평가될 수 있는 문이고, 문에는 표현식인 문과 표현식이 아닌 문이 있다.
할당문은 표현식인 문일까, 표현식이 아닌 문일까?
var x; // 할당문은 표현식인 문이다. console.log(x = 10) // 10
할당 문은 변수에 값을 할당하는 부수효과만 있을 뿐 값으로 평가되지 않는 것처럼 보인다.
하지만 할당문은 값으로 평가되는 표현식인 문으로서 할당된 값으로 평가된다.
비교연산자
비교 연산자는 좌항과 우항의 피연산자를 비교한 다음 그 결과를 불리언 값으로 반환한다.
if문이나 for문 같은 제어문의 조건식에 주로 사용한다.
동등/일치 비교 연산자
동등 비교 연산자와 일치 비교 연산자로 구분하는데
연산자 의미 부수 효과 사용 사례 설명 == 동등 비교 없음 두 값이 같은지 비교하되, 타입이 다르면 타입 변환을 거쳐 비교합니다. 예: 0 == '0'는 true === 일치 비교 없음 두 값이 타입까지 포함하여 완전히 같은지 비교합니다. 예: 0 === '0'는 false != 부동등 비교 없음 두 값이 다른지 비교하되, 타입이 다르면 타입 변환을 거쳐 비교합니다. 예: 0 != '1'는 true !== 불일치 비교 없음 두 값이 타입까지 포함하여 완전히 다른지 비교합니다. 예: 0 !== '0'는 true 이렇게 구분한다.
동등 (==) 비교 연산자는 좌항과 우항의 피연산자를 비교할 때 먼저 암묵적 타입 변환을 통해 타입을 일치 시킨 후 같은 값인지 비교한다. 따라서
결과를 예측하기 어렵고 실수하기 쉽다.
// 동등 비교 5 == '5' // true // 일치 비교 5 === '5' // false
일치 비교 연산자에서 주의할 값은 NaN이다. 자기자신을 비교해도 false를 반환한다.
NaN === NaN // false // NaN인지 조사하려면 빌트인 함수 Number.isNaN을 사용해 비교한다. Number.isNaN(NaN) // true Number.isNaN(10) // false Number.isNaN(1 + undefined) // true // 숫자 0도 조심해야한다. 0 === -0 // true 0 == -0 // true
이번에 ES6에 도입된 함수 Object.is() 대해 살펴보자
Object.is() 메서드
ES6(ECMAScript 2015)에서 도입된
Object.is()
메서드는 두 값을 정확하게 비교하여 그 결과를 불리언 값으로 반환합니다. 이 메서드는 일반적인 비교 연산자(===
)와 비슷한 동작을 하지만, 일부 특별한 경우에 다르게 동작하여 더 엄격한 비교를 수행합니다.Object.is()
는 주로 다음과 같은 경우에===
연산자와 다른 결과를 보입니다:NaN의 비교:
NaN
은 자기 자신과도 동등하지 않다고 평가되는 유일한 값입니다(NaN === NaN
은false
). 하지만,Object.is(NaN, NaN)
은true
를 반환합니다.0과 -0의 비교:
+0
과0
은===
연산자를 사용할 경우 동등하다고 평가됩니다(+0 === -0
은true
). 반면,Object.is(+0, -0)
은false
를 반환하여 이 두 값이 실제로는 다르다는 것을 정확하게 반영합니다.사용 예시
NaN의 비교:
console.log(NaN === NaN); // false console.log(Object.is(NaN, NaN)); // true
이 예시는
NaN
이 자기 자신과도 동등하지 않다고 평가되는 JavaScript의 특성을 보여줍니다. 하지만Object.is()
를 사용하면NaN
값끼리의 비교에서true
를 얻을 수 있어, 두 값이 실제로 동일한NaN
임을 정확하게 확인할 수 있습니다.0과 -0의 비교:
console.log(+0 === -0); // true console.log(Object.is(+0, -0)); // false
이 예시는
+0
과-0
이 엄밀히는 다른 값임에도 불구하고===
연산자로는 둘을 구분할 수 없다는 것을 보여줍니다.Object.is()
메서드를 사용하면 이 두 값이 실제로 다르다는 것을 확인할 수 있습니다.객체의 비교:
const obj1 = { name: 'JavaScript' }; const obj2 = { name: 'JavaScript' }; const obj3 = obj1; console.log(Object.is(obj1, obj2)); // false, 두 객체는 내용은 같지만 서로 다른 메모리 주소를 가리킵니다. console.log(Object.is(obj1, obj3)); // true, obj3는 obj1과 같은 객체를 참조합니다.
이 예시는 객체 비교에서
Object.is()
가 참조를 비교한다는 것을 보여줍니다.obj1
과obj2
는 내용이 같더라도 다른 객체이므로false
를 반환합니다. 반면,obj3
는obj1
과 동일한 객체를 참조하므로true
를 반환합니다.
Object.is()
메서드는 이러한 특수한 경우에 정확한 비교가 필요할 때 유용하게 사용할 수 있습니다.
삼항 조건 연산자
삼항 조건 연산자는 조건식의 평가 결과에 따라 반환값을 결정한다.
자바스크립트의 유일한 삼항연산자 이며 부수효과는 없다.
조건식 ? 조건식이 true일때 반환값 : 조건식이 false일때 반환값
형태이다.
const x = 5;
var result = x === 5 ? x + 1 : x - 1; // x === 5 값이 true 이기 때문에
console.log(result) // 6
삼항 조건 연산자의 첫 번째 피연산자는 조건식이므로 삼항 조건 연산자 표현식은 조건문이다.
삼항 조건 연산자와 if…else문은 중요한 차이가 있다.
// 삼항 조건 연산자 표현식은 값처럼 사용할 수 있지만 // if...else문은 값처럼 사용할 수 없다. var x = 10; var result = if(x % 2) { result = '홀수' } else { result = '짝수' }; // SyntaxError : Unexpected token if // 삼항 조건 연산자 표현식은 표현식인 문이다. 따라서 값처럼 사용 가능 var result = x % 2 == 0 ? result = '짝수' : result = '홀수'; // 가능하다
논리 연산자
논리 연산자 | 의미 | 부수 효과의 가능성 |
---|---|---|
&& | AND 연산자. 첫 번째 피연산자가 false로 평가되면 두 번째 피연산자를 평가하지 않고 첫 번째 값을 반환합니다. 모두 true라면 마지막 피연산자의 값을 반환합니다. | 피연산자 중 하나 이상이 부수 효과를 발생시키는 표현식인 경우에만 부수 효과 발생 가능. |
! | NOT 연산자. 주어진 표현식의 불리언 값을 반전시킵니다. | 피연산자가 부수 효과를 발생시키는 표현식인 경우에만 부수 효과 발생 가능. |
ex)
let a = 0;
function increaseA() {
a += 1; // 'a'의 값을 변경하는 부수 효과가 있는 함수
return true;
}
// 'increaseA' 함수 호출은 부수 효과를 발생시키며, '&&' 연산자는 이를 평가합니다.
const result = increaseA() && true; // 'a'는 1로 증가합니다.
// 압묵적 타입 변환
!0; // true
!'Hello'; // false
// 단축 평가
'Cat' && 'Dog' // Dog
쉼표 연산자
쉼표 연산자는 왼쪽 피연산자부터 차례대로 피연산자를 평가하고 마지막 피연산자의 평가가 끝나면 마지막 평가 결과를 반환 한다.
var x, y, z;
x = 1, y = 2, z = 3 // 3
그룹 연산자
소괄호로 피연산자를 감싸는 그룹 연산자는 자신의 피연산자인 표현식을 가장 먼저 평가한다.
그룹 연산자를 사용하면 연산자의 우선순위를 조절할 수 있다.
그룹 연산자는 연산자 우선순위가 가장 높다.
typeof 연산자
typeof 연산자는 피연산자의 데이터 타입을 문자열로 반환한다.
typeof 연산자는 7가지 타입을 문자열로 반환하는데
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에서 도입된 지수 연산자는 좌항의 피연산자를 밑으로, 우항의 피연산자를 지수로 거듭 제곱하여 숫자값을 반환한다.
2 ** 2 // 4
2 ** 2.5 // 5.6585424949238
2 ** 0 // 1
2 ** -2 // 0.25
지수 연사자가 도입되기 전에는 Math.pow 메서드를 사용
Math.pow(2, 2) // 4
Math.pow(2, 2.5) // 5.6585424949238
Math.pow(2, 0) // 1
Math.pow(2, -2) // 0.25
음수를 거듭제곱 밑으로 사용해 계산
-5 ** 2; // x
(-5) ** 2; // 25
연산자의 부수효과
부수 효과가 있는 연산자들은 프로그램의 상태를 변경하거나 외부와 상호작용을 하는 연산자들입니다. 주로 변수에 대한 할당, 증가, 감소 등의 연산이 여기에 속합니다. 아래는 부수 효과가 있는 연산자들과 그 예시 코드입니다.
예시 코드 및 설명
- 할당 연산자 (
=
)
let a = 5; // 변수 'a'에 5를 할당. 'a'의 값이 변경되므로 부수 효과가 있음.
- 증가 연산자 (
++
)
let count = 0;
count++; // 'count'의 값을 1 증가. 변수의 상태가 변경되므로 부수 효과가 있음.
- 감소 연산자 (
-
)
let count = 10;
count--; // 'count'의 값을 1 감소. 변수의 상태가 변경되므로 부수 효과가 있음.
- 복합 할당 연산자 (
+=
,=
,=
,/=
, etc.)
let total = 0;
total += 5; // 'total'에 5를 더하고 결과를 'total'에 할당. 변수의 상태가 변경되므로 부수 효과가 있음
연산자 우선순위
우선순위 | 연산자 |
---|---|
1 | (), [], . |
2 | !, ~, ++, --, typeof, void, delete |
3 | ** |
4 | *, /, % |
5 | +, - |
6 | <<, >>, >>> |
7 | <, <=, >, >=, in, instanceof |
8 | ==, !=, ===, !== |
9 | & |
10 | ^ |
11 | ` |
12 | && |
13 | ` |
14 | ? : (조건부 연산자) |
15 | =, +=, -=, *=, /=, %=, etc. |
16 | , |
'Javascript' 카테고리의 다른 글
자바스크립트 타입 변환과 단축 평가? (0) | 2024.04.09 |
---|---|
자바스크립트 제어문이란? (1) | 2024.04.09 |
자바스크립트 데이터 타입은 뭐가 있지? (0) | 2024.04.09 |
표현식과 문은 무엇일까? (0) | 2024.04.09 |
자바스크립트의 변수의 동작원리 (0) | 2024.04.09 |