모던 자바스크립트 Deep Dive 7장
연산자는 하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입, 지수연상등을 수행해 하나의 값을 만든다
연산의 대상은 피연산자라고 함 피연산자는 값으로 평가될 수 있는 표현식이여야 함
연산자는 피연산자를 연산해 새로운 값을 만든다
이때 산술연산이 불가능한 경우 NaN을 반환한다고 함
NaN이란?
난은 예상외로 값이 없음은 아니고 특정 데이터 타입 안에서 정의된 특수 값 (special value)라고 함
그래서 typeof NaN 을 찍어보면 number라고 나온다고 함 (세상에)
숫자가 꺠졌을 뿐이지 안에 뭔가 값은 있다고 함
Number는 64비트를 먹는데 exponent 비트가 전부 1이면 NaN으로 판단, 그 외의 값은 NaN끼리도 다 다름
63 | 62 ~ 52 | 51 ~ 0
sign | exponent | fraction
이게 Number의 내부 구조인데 더 환장하는게 exponent 비트가 전부 1이고 fraction 비트의 첫자리가 1이면 NaN, 전부 0이면 또 +Infinity 라고 한다.
그래서 NaN === NaN은 fraction 비트의 차이에 의해 false가 나온다고 함
반대로 Infinity === Infinity 는 true임 ㅋㅋ진짜 얼탱없는데 NaN이 Not a Number라고 한다
숫자라매
크아악
산술 연산자 (Arithmetic Operator)
이항 산술 연산자
2개의 피연산자를 산술 연산하여 숫자 값을 만든다
피연산자의 값을 변경하는 side effect가 없음
5 + 2 // 7
단항 산술 연산자
1개의 피연산자를 산술 연산함
이떄 증가/감소(++/--) 연산자는 피연산자의 값을 변경하는 부수효과가 있다
증감 연산을 하면 피연산자의 값을 변경하는 암묵적 할당이 이뤄짐
var x = 1;
x++; // x = x + 1
console.log(x); // 2
x--; // x = x - 1
console.log(x); // 1
증감 연산자는 위치에 의미가 있음
대충 할당 먼저, 연산 먼저의 차이임
단항 산술 연산자는 대상을 숫자로 만든다 이때 부호는 바뀌지 않음
자기 맘대로 편수의 타입을 바꿔버리는게 인상적임
근데 이때 Hello같이 숫자로 변환이 불가능한 값은 NaN이 된다고 함
NaN 자체가 시도는 해봤다는건데
+true // <- 1
+1 // <- 1
+(-1) // <- -1
+'1' // 1 환장하겠네
+'Hello' // NaN
그렇다면 왜 +'Hello' 는 NaN일까?
이건 ToNumber('Hello') 로 동작하는데 ECMAScript 명세의 알고리즘에 의해 숫자로 변환을 시도함
- 문자열의 타입을 확인함 > input = "Hello", type = String
- 엔진 내부에서 이런걸 시도 > "Hello" → 숫자로 해석 가능한가?
- 파싱 실패 > "Hello" → 숫자 문법에 맞지 않음
- 명세에 따라 NaN 반환 > Number("Hello") === NaN
그나마 사이드이펙트는 없다고 함
var x = '1';
console.log(+x); // 1
console.log(x); // '1'
뭐 -도 부호만 반전시키지 동작은 + 랑 똑같음
문자열 연결 연산자
피연산자중 하나만 문자열이여도 문자열 연결 연산자로 동작한다고 함
'1' + 2; // '12'
'1' + true // 1ture ㅋㅋ 레죵드
이 난리 부르스가 자바스크립트 엔진에서 암묵적으로 수행하는 '암묵적 타입 변환' 또는 '타입 강제 변환' 이라고 한다
9장에서 더 자세하게 다룬다고 함 (크아악)
할당 연산자 (Assignment Operator)
할당연산자는 짱쉬움
무지성 할당('=') or 그냥 단항 산술 연산자('++')에 얼마 더할지만 값으로 전해준다고 생각하면 됌
따라서 side effect가 발생해 변수값 자체가 변경됨
var x;
x = 10;
console.log(x); // 10 무지성 할당
x += 5;
console.log(x); // 15
골때리는게 문자열도 문자열 연결 연산자로 해석되어 가능
var lunch = 'i love '
lunch += 'Vertex'
console.log(lunch); // i love Vertex (번외로 버텍스는 정말 맛있다)
표현식은 값으로 평가될 수 있는 문이다.
문에는 표현식인 문이 있고 아닌 문이 있는데 할당문은 표현식인 문임
var x;
console.log(x = 10); // 10
var a, b, c;
a = b = c = 0;
console.log(a, b, c); // 0, 0, 0
할당 연산자(=)는 right-associative (오른쪽 결합) 라고 함
비교 연산자 (Comparison Operator)
비교 연산자는 좌항과 우항의 피연산자를 비교한 다음 그 결과를 불리언 값으로 변환함
동등/일치 비교 연산자
== 은 동등비교, 값만 체크한다
=== 은 일치비교, 타입까지
!= 은 부동등 비교 (부동동 ㅋㅋ 먼가 웃김), 이것도 값만 다른지
!== 은 불일치 비교 , 이것도 타입까지
이것도 골때리는게 값만 체크한다는게 참
5 == '5'; // true
얼탱이가 없음 그냥
앵간하면 쓰지말자 그냥
// 양의 0과 음의 0의 비교, 일치 비교/동등 비교 모두 true
0 === -0
0 == -0
이것도 얼탱이가 없음
왜나눴을까
이건 두배로 얼탱이가 없는게 비트로 따져봤을때 sign 값이 분명하게 1, 0 으로 다름
근데 그냥 수학적 직관때문에 유지했다고 함
1 / Infinity // 0
1 / -Infinity // -0
극한의 방향성에서 자연스럽다네용
그래서 예측 가능한 비교결과를 지원하기 위해 Object.is 를 도입했다고 함
NaN === NaN // false
Object.is(NaN, NaN) // true
0 === -0 // true
Object.is(0, -0) // false
뭐가 더 맞는지는 나도 몰루?
대소 관계 비교 연산자
이건 그냥 부등호임
삼항 조건 연산자 (Ternary Operator)
무려 3가지 피연산자의 콜라보
첫번째 피연산자가 true로 평가되면 두번째 피연산자를 반환하고, 첫번째 피연산자가 false로 평가되면 세번쨰 피연산자를 반환한다
var x = 2;
// 표현식임
var result = x % 2 ? '홀수' : '짝수';
console.log(result); // 짝수
그럼 if else랑 다른게 뭐냐! 라고 물으면
삼항 연산자의 표현식은 값으로 사용할 수 있다는것
var x = 2;
// 표현식이 아님
var result = if (x % 2) {reesult = '홀수'} else { result = '짝수' } ;
// SyntaxError
논리 연산자 (Logical Operator)
||, &&, ! 이 있음
우항과 좌항의 피연산자를 논리연산함 (우항좌항 ㅋㅋ)
! 부정 연산자는 우항만 논리연산
단순 or, and, not 연산을 함
이때 javascript 특유의 암묵적 타입변환이 적용
!0; // true
!'Hello'; // false
결과값을 불리언으로 강제해버리는 무시무시한 모습
'Cat' && 'Dog'; // 'Dog'
'Cat' || 'Dog'; // 'Cat'
뭣
이렇게 보니깐 괴랄해보이지 실제로 쓰는거 보면 이해된다
const name = input || 'default'; // input값이 falsy면 'default' 사용
isLoggedIn && doSomething(); // 로그인 상태일때만 실행
쉼표 연산자 (Comma Operator)
이건 왜있지
var x, y, z;
x = 1, y = 2, z = 3; // 3
차례대로 피연산자를 평가하고 마지막 피연산자의 평가가 끝나면 마지막 피연산자의 평가 결과를 반환
코테에서 가끔 썼는데 마지막 값 반환하는건 몰랐음
그룹 연산자 (Group Operator)
() 소괄호로 우선순위 조절함
끗임
typeof 연산자
{typeof 동작 방식 및 반환값}
typeof 42; // "number"
typeof 3.14; // "number"
typeof NaN; // "number"
typeof Infinity; // "number"
typeof "hello"; // "string"
typeof ''; // "string"
typeof true; // "boolean"
typeof false; // "boolean"
typeof undefined; // "undefined"
let x;
typeof x; // "undefined"
typeof Symbol(); // "symbol"
typeof 10n; // "bigint"
typeof {}; // "object"
typeof { a: 1 }; // "object"
typeof []; // "object"
typeof null; // "object"
typeof function(){}; // "function"
typeof class A {}; // "function"
typeof notDefined; // "undefined"
null이 object를 반환하는건 자스 버그라고 함 ㅋㅋ
null인지 확인하려면 === 로 비교해야한다고 함
var foo = null;
typeof foo === null; // false
foo === null; // true
지수 연산자 (Exponentiation Operator)
좌항의 피연산자를 밑으로, 우항의 피연산자를 지수로 거듭제공한다
Math.pow보다 가독성이 좋음
2 ** (3 ** 2); // 512
Math.pow(2, Math.pow(3, 2)); // 512 크아악
음수에 적용하려면 괄호로 묶어야 한다고 함
(-5) ** 2; // 25
핵심 포인트
NaN이 좀 기억에 남는다
참고 자료
- 모던 자바스크립트 Deep Dive (이웅모 저) 7장
- [[Expression and Statement]]
- [[Data Type]]
'코딩딩 > Javascript' 카테고리의 다른 글
| 날것 - 타입 변환과 단축 평가 (0) | 2026.04.01 |
|---|---|
| 날것 - 제어문 (Control Flow Statements) (0) | 2026.03.25 |
| JavaScript 마이크로태스크 큐, 왜 먼저 실행되는 건데? (0) | 2026.03.13 |
| 날것 - 데이터 타입 (0) | 2026.03.11 |
| 날것 - 표현식과 문 (0) | 2026.03.11 |