Language/JavaScript

[JS] πŸ“š 재미있게 ν™•μ‹€νžˆ μ΄ν•΄ν•˜λŠ” null / undefined / NaN 차이

인파_ 2023. 4. 14. 09:47

null-NaN-undefined

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μš”μƒν•œ falsy κ°’

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ null, NaN, undefinedλŠ” λ‹€λ₯Έ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—λŠ” μ—†λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ—λ§Œ μžˆλŠ” μš”μƒν•œ falsy κ°’μœΌλ‘œμ„œ, μ΄λ“€μ€ λͺ¨λ‘ 값이 μ—†μŒ(falsy)을 λ‚˜νƒ€λ‚΄λŠ” νŠΉλ³„ν•œ 값이닀. κ·Έλž˜μ„œ 이듀은 μ‘°κ±΄λ¬Έμ—μ„œ false둜 ν‰κ°€λ˜μ–΄ 진닀.

κ°’ Boolean λ¬Έλ§₯ Number λ¬Έλ§₯ String λ¬Έλ§₯
null false 0 "null"
undefined false NaN "undefined"
NaN false NaN "NaN"
Infinity true Infinity "Infinity"

ν•˜μ§€λ§Œ λŒ€λΆ€λΆ„ null, NaN, undefined κ°„μ˜ 의미의 ꡬ체적인 차이에 λŒ€ν•΄ 애맀λͺ¨ν˜Έν•˜κ²Œ μ•Œκ±°λ‚˜ μ •ν™•νžˆ λͺ¨λ₯΄λŠ” μ‚¬λžŒμ΄ κ½€ λ§Žλ‹€. λ”°λΌμ„œ 이번 ν¬μŠ€νŒ…μ—λŠ” null, NaN, undefined값을 λ‘λ£¨λ§ˆλ¦¬ νœ΄μ§€λ‘œ λΉ„μœ ν•œ 이미지λ₯Ό 톡해 μ •ν™•νžˆ μ–΄λ–€ 의미이며 μ™œ μ΄λŸ¬ν•œ μ˜λ―ΈμΈμ§€ μ•Œμ•„λ³΄λŠ” μ‹œκ°„μ„ κ°€μ Έ 보겠닀.


λ‘λ£¨λ§ˆλ¦¬ νœ΄μ§€λ‘œ λΉ„μœ ν•˜λŠ” falsy κ°’

null-NaN-undefined

μœ„ μ΄λ―Έμ§€λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ falsy 값에 λŒ€ν•œ μΌμ’…μ˜ 유머적 λΉ„μœ μ΄λ‹€. λͺ¨λ‘ 의미 μ—†κ±°λ‚˜ λΆ€μ μ ˆν•œ κ°’λ“€μ΄μ§€λ§Œ νœ΄μ§€ ν˜•νƒœμ— 따라 ν™•μ‹€νžˆ μ˜λ―Έν•˜λŠ” λ°”κ°€ 닀름을 λ³Ό 수 μžˆλ‹€. 이듀 4개의 값을 μ„€λͺ…ν•˜μžλ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

0 의 μƒνƒœ 

μ •μˆ˜ 0은 λŒ€λ‹€μˆ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ false둜 ν‰κ°€λœλ‹€. 이λ₯Ό νœ΄μ§€λ‘œ λΉ„μœ ν•˜λ©΄ νœ΄μ§€ λ‚΄μš©λ¬Όμ΄ μ—†λ‹€λŠ” μ˜λ―Έμ΄λ‹€. 단, 0 이라도 κ³ μœ ν•œ 숫자 νƒ€μž… 이듯이 νœ΄μ§€ λ‚΄μš©λ¬Όμ΄ 없어도 νœ΄μ§€μž„μ„ μ•Œ 수 μžˆλŠ” 'κ³½ν‹°μŠˆ' 와 이λ₯Ό λ‹΄λŠ” 'νœ΄μ§€κ±Έμ΄'λŠ” μž”μ‘΄ν•œλ‹€.

null-NaN-undefined


null 의 μƒνƒœ

보톡 null을 κ·Έμ € 값이 μ—†λŠ” μƒνƒœλΌκ³  μ•Œκ³  μžˆλŠ” 뢄듀이 λ§Žμ§€λ§Œ, μ΄λŠ” μ •ν™•ν•˜μ§€ μ•Šμ€ μ˜λ―Έμ΄λ‹€. μ •ν™•νžˆ null은 μ–΄λŠ reference λ³€μˆ˜μ— λŒ€ν•΄ μ£Όμ†Œκ°’μ΄ μ—†λŠ” 것을 ν‘œν˜„ν•˜κΈ° μœ„ν•œ ν‚€μ›Œλ“œ 값이닀. 객체의 속성 값이 μ‘΄μž¬ν•˜μ§€ μ•Šμ„ λ•Œλ‚˜ ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” μš©λ„λ‘œ μ‚¬μš© λ˜κΈ°λ„ ν•œλ‹€.

레퍼런슀 λ³€μˆ˜λž€ 객체와 같이 νž™(heap) 곡유 λ©”λͺ¨λ¦¬ μ˜μ—­μ— μ €μž₯λ˜λŠ” 포인터 라고 μ΄ν•΄ν•˜λ©΄ λœλ‹€.

그런데 null은 μ˜€λ‘œμ§€ reference λ³€μˆ˜μ—λ§Œ 담을 수 있기 λ•Œλ¬Έμ—, 일반적인 값인 μ •μˆ˜λ‚˜ 문자λ₯Ό μ €μž₯ν•˜λŠ” primitive λ³€μˆ˜μ—λŠ” null을 μ €μž₯ν•  수 μ—†λ‹€. λ”°λΌμ„œ Javaμ—μ„œλŠ” 이 primitive λ³€μˆ˜μ— λŒ€ν•΄ 값을 주지 μ•Šμ„ 경우 μ§€μ •λœ μ΄ˆκΈ°ν™” 값을 μžλ™μœΌλ‘œ ν• λ‹Ήν•˜κ²Œ ν•˜μ˜€κ³ , Cμ–Έμ–΄μ—μ„œλŠ” 가비지 값을 μžλ™μœΌλ‘œ ν• λ‹Ήν•œλ‹€.

#include <stdio.h>

int main() {
   int num;
   printf("%d", num); // -56982792084 μ΄μƒν•œ μ“°λ ˆκΈ° κ°’
   return 0;
}
public class MyClass {
    int number; // μΈμŠ€ν„΄μŠ€ λ³€μˆ˜

    public static void main(String[] args) {
        MyClass obj = new MyClass();
        System.out.println(obj.number); // 좜λ ₯ κ²°κ³Ό: 0 (μ›λž˜λŠ” Cμ–Έμ–΄ 처럼 μ“°λ ˆκΈ°κ°’μ΄ λ‚˜μ˜€μ§€λ§Œ JVM에 μ˜ν•΄μ„œ κΈ°λ³Έκ°’μœΌλ‘œ μ„€μ •λœλ‹€)
    }
}

reference λ³€μˆ˜λƒ  primitive λ³€μˆ˜λƒ 에 따라 νƒ€μž…μ΄ μ—†λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œλ„ μ•Œμˆ˜κ°€ μžˆλŠ”λ°, 1을 ν• λ‹Ήν•œ λ³€μˆ˜μ˜ νƒ€μž…μ€ number νƒ€μž…μ΄μ§€λ§Œ, null을 ν• λ‹Ήν•œ λ³€μˆ˜μ˜ νƒ€μž…μ€ object μž„μ„ μ•Œ μˆ˜κ°€ μžˆλ‹€. 

null-NaN-undefined

결둠적으둜, μœ„μ˜ 0κ³Ό λ‹€λ₯Έμ μ€ κ³½ν‹°μŠˆλŠ” μ—†μ§€λ§Œ νœ΄μ§€κ±Έμ΄λŠ” μž”μ‘΄ν•΄ μžˆλ‹€λŠ” 점이닀. μ™œλƒν•˜λ©΄ null 값을 λ“€κ³  μžˆλŠ” 객체 μžμ²΄λŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ •μ˜ν•˜μ—¬ λ©”λͺ¨λ¦¬μ— 올렀져 μ£Όμ†Œκ°’μ„ 받은 μ€€λΉ„κ°€ λ˜μ–΄ 있기 λ•Œλ¬Έμ΄λ‹€.

즉, 값은 μ—†μ§€λ§Œ 값을 담을 수 μžˆλŠ” 그릇은 μžˆλŠ” 것이닀. λ”°λΌμ„œ νœ΄μ§€λ₯Ό λ‹΄λŠ” νœ΄μ§€κ±Έμ΄ μžμ²΄λŠ” μž”μ‘΄ν•΄ μžˆλŠ” 것이닀.

null-NaN-undefined


undefined 의 μƒνƒœ

undefinedλŠ” λ³€μˆ˜κ°€ μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šμ€ μƒνƒœ, 즉 값이 ν• λ‹Ήλ˜μ§€ μ•Šμ€ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

λ°”λ‘œ μœ„μ—μ„œ primitive, reference λ³€μˆ˜λ₯Ό λ“€λ©° μžλ°”μ™€ Cμ–Έμ–΄μ—μ„œ μ–΄λ–»κ²Œ μ΄ˆκΈ°ν™”λ₯Ό μ§„ν–‰ν•˜λŠ”μ§€μ— λŒ€ν•΄ μ„€λͺ…ν•˜μ˜€μ—ˆλ‹€. 두 μ–Έμ–΄λ§Œ ν•˜λ”λΌλ„ μ–΄λ–€ νƒ€μž…μ˜ λ³€μˆ˜λƒμ— 따라 μ΄ˆκΈ°ν™”λ˜λŠ” 과정이 λ‹¬λžλ‹€.

λ”°λΌμ„œ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„  μ‹¬ν”Œν•˜κ²Œ μ–΄λ–€ νƒ€μž…μ˜ λ³€μˆ˜λ“  간에 값이 μ—†λ‹€λŠ”κ±Έ undefined λΌλŠ” ν‘œν˜„μœΌλ‘œ 퉁쳀닀고 보면 λœλ‹€. 심지어 λ³€μˆ˜ νƒ€μž… μžμ²΄λ„ undefined 둜 λ˜μ–΄ μžˆλ‹€. μ‹¬ν”Œν•˜κ²Œ ν‘œν˜„ν•˜κΈ° μœ„ν•΄ μ΄λŸ¬ν•œ 방식을 μ·¨ν•œκ²ƒ 같은데, 만일 기쑴의 Cμ–Έμ–΄λ‚˜ μžλ°”μ— μ΅μˆ™ν•œ κ°œλ°œμžλ“€μ—κ² 였히렀 ν˜Όλ™λ§Œ μΌμœΌν‚¨ 것 κ°™λ‹€κ³  개인적으둜 μƒκ°λœλ‹€.

 

null vs undefined

nullκ³Ό undefined 차이점은 λ‚΄λΆ€ λ©”λͺ¨λ¦¬μ μΈ μΈ‘λ©΄μ—μ„œ 봐야 λœλ‹€. 

undefinedλŠ” λ³€μˆ˜κ°€ μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ•˜κ±°λ‚˜, 객체의 속성이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ“±μ˜ κ²½μš°μ— μžλ™μœΌλ‘œ ν• λ‹Ήλ˜λŠ” κ°’μœΌλ‘œ, μ΄λ•Œμ˜ λ³€μˆ˜λŠ” λ©”λͺ¨λ¦¬μ— μ‘΄μž¬ν•˜μ§€λ§Œ 값이 μ—†κΈ° λ•Œλ¬Έμ— 크기가 맀우 μž‘λ‹€.

반면, null은 κ°œλ°œμžκ°€ μ˜λ„μ μœΌλ‘œ 값이 μ—†μŒμ„ ν• λ‹Ήν•œ κ²½μš°μ— μ‚¬μš©λ˜λŠ” κ°’μœΌλ‘œ, μ΄λ•Œμ˜ λ³€μˆ˜λŠ” 빈 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” 객체 포인터이기 λ•Œλ¬Έμ— μ£Όμ†Œκ°’μ„ λ‚˜μ€‘μ—λΌλ„ λ°›κΈ°μœ„ν•΄ 크기가 μžˆμ–΄ λ©”λͺ¨λ¦¬λ₯Ό μ°¨μ§€ν•˜κ²Œ λœλ‹€.

λ”°λΌμ„œ, undefined 값을 가진 λ³€μˆ˜μ˜ λ©”λͺ¨λ¦¬ μš©λŸ‰μ€ μž‘κ³ , null 값을 가진 λ³€μˆ˜μ˜ λ©”λͺ¨λ¦¬ μš©λŸ‰μ€ 크닀고 정리할 수 μžˆκ² λ‹€. (μ΄λŠ” μƒλŒ€μ μΈ 비ꡐ일 λΏμ΄λ―€λ‘œ μ‹€μ œλ‘œλŠ” 거의 차이가 μ—†λ‹€κ³  봐도 λœλ‹€)

λ‹€λ§Œ, μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” λ³€μˆ˜κ°€ 컴파일 μ‹œμ μ΄ μ•„λ‹Œ λŸ°νƒ€μž„ μ‹œμ μ— λ™μ μœΌλ‘œ ν• λ‹Ήλ˜κΈ° λ•Œλ¬Έμ—, λ³€μˆ˜μ˜ ν¬κΈ°λŠ” λŸ°νƒ€μž„ ν™˜κ²½μ— 따라 λ‹€λ₯Ό 수 μžˆμ–΄ λ©”λͺ¨λ¦¬ ν¬κΈ°λŠ” μ •ν™•νžˆ μ•Œ 수 μ—†λ‹€.

반면 μžλ°”(Java)에선 reference λ³€μˆ˜ 같은 경우  32λΉ„νŠΈ JVM κΈ°μ€€μœΌλ‘œ 4λ°”μ΄νŠΈκ°€ ν• λ‹Ήλ˜κ²Œ λœλ‹€.

null κ³Ό undefinedκ°€ μ„œλ‘œ μ™„μ „νžˆ λ‹€λ₯Έ μ‘΄μž¬λΌλŠ” 점은, μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ νƒ€μž…μ„ 좜λ ₯해보면 μ•Œ 수 μžˆλ‹€.

undefined
null κ³Ό undefined 비ꡐ

λ§ˆμ§€λ§‰μœΌλ‘œ νœ΄μ§€λ‘œ λΉ„μœ ν•œ 그림을 보면 μ•„μ˜ˆ 빈 κ³΅κ°„μž„μ„ λ³Ό μˆ˜κ°€ μžˆλŠ”λ°, νœ΄μ§€ λ‚΄μš©λ¬Όλ„ κ·Έ νœ΄μ§€λ₯Ό 담을 νœ΄μ§€κ±Έμ΄ μžμ²΄λ„ μ—†κΈ° λ•Œλ¬Έμ΄λ‹€. μ™œλƒν•˜λ©΄ νƒ€μž… μžμ²΄κ°€ undefined 이기 λ•Œλ¬Έμ΄λ‹€.

undefined

μœ„μ—μ„œ null을 λΉ„μœ ν• λ•Œ 아무것도 담기지 μ•Šμ€ 그릇이라 ν‘œν˜„ν–ˆλŠ”λ°, undefinedλŠ” 그릇 μžμ²΄κ°€ ν†΅μ§Έλ‘œ μ—†λŠ” 것이닀.

undefined


NaN 의 μƒνƒœ 

NaN은 Not a Number의 μ•½μžλ‘œ μˆ«μžκ°€ μ•„λ‹Œ 값을 λ‚˜νƒ€λ‚Έλ‹€. κ·ΈλŸ¬λ‚˜ μˆ«μžκ°€ μ•„λ‹ˆμ§€λ§Œ νƒ€μž…μ€ Number νƒ€μž…μœΌλ‘œ μ·¨κΈ‰λœλ‹€. 숫자 νƒ€μž…μ΄λ©΄μ„œ μˆ«μžκ°€ μ•„λ‹Œ κ°’μ΄λΌλ‹ˆ λ­”κ°€ 말이야 방ꡬ야 μ‹Άκ² μ§€λ§Œ, μ‹€μ œλ‘œ μ΄λŸ¬ν•œ ν‘œν˜„μ— λŒ€ν•œ ν•„μš”μ„±μ΄ μ‘΄μž¬ν•œλ‹€.

예λ₯Όλ“€μ–΄ 문자 "100" 을 숫자 νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•˜λ©΄ μ–΄λ– ν•œ μ—λŸ¬ 없이 숫자 100으둜 μΉ˜ν™˜μ΄ λœλ‹€. μ΄λŸ¬ν•œ κΈ°λŠ₯이 μžˆλŠ” μ΄μœ λŠ” λŒ€λΆ€λΆ„μ˜ μ‚¬μš©μžκ°€ μž…λ ₯ν•œ 값이 λ¬Έμžμ—΄ ν˜•νƒœμΈ κ²½μš°κ°€ λ§Žμ•„ 이λ₯Ό 숫자둜 λ³€ν™˜ν•˜μ—¬ 계산해야 ν•˜λŠ” 상황이 많기 λ•Œλ¬Έμ΄λ‹€.

NaN
λŒ€ν‘œμ μœΌλ‘œ form에 μž…λ ₯ν•œ λͺ¨λ“  값은 λ¬Έμžμ—΄μ΄λ‹€

그런데 ν•΄λ‹Ή λ¬Έμžκ°€ "100ABC" 와 같은 μˆ«μžμ™€ 일반 λ¬Έμžμ—΄μ΄ μ„žμΈ ν˜•νƒœμΌ 경우, 이λ₯Ό ν•¨μˆ˜λ₯Ό 톡해 숫자둜 λ³€ν™˜ν• λ•Œ λ¬Έμ œκ°€ λœλ‹€. κ·Έλž˜μ„œ νƒ€μž… μžμ²΄λŠ” λ„˜λ²„ νƒ€μž…μœΌλ‘œ λ³€ν™˜μ€ λ¬μ§€λ§Œ λ‚΄μš©λ¬Όμ΄ μˆ«μžκ°€ μ•„λ‹ˆλΌλŠ” 값을 ν‘œν˜„ν•˜κΈ° μœ„ν•΄ NaN μ΄λΌλŠ” ν‘œν˜„μ„ μ“°λŠ” 것이닀. κ·Έλž˜μ„œ NaN은 μΌμ’…μ˜ 였λ₯˜ κ°’μœΌλ‘œ μ·¨κΈ‰λœλ‹€. 이밖에도 μˆ«μžμ™€ λ¬Έμžμ—΄μ„ μ—°μ‚°ν•˜λ €κ³  해도 NaN이 λ°œμƒν•œλ‹€.

반면 μžλ°”(Java)에선 λ¬Έμžμ—΄μ΄ μœ νš¨ν•œ 숫자 ν˜•μ‹μ΄ μ•„λ‹κ²½μš° NumberFormatException을 λ°œμƒμ‹œν‚¨λ‹€.
// 문자 100을 + μ—°μ‚°μžλ₯Ό 톡해 숫자둜 ν˜•λ³€ν™˜
let a = +"100"; 
console.log(a); // 숫자 100

// 문자 ABCλ₯Ό  + μ—°μ‚°μžλ₯Ό 톡해 숫자둜 ν˜•λ³€ν™˜
let b = +"ABC";
console.log(b); // NaN (숫자둜 ν˜•λ³€ν™˜ν•΄μ„œ 숫자 νƒ€μž… κ°’μ΄μ§€λ§Œ μˆ«μžκ°€ μ•„λ‹˜)

NaN

이λ₯Ό νœ΄μ§€λ‘œ λΉ„μœ ν•˜λ©΄ '이 값은 말도 μ•ˆ λ˜λŠ” κ°’'μ΄λΌλŠ” λœ»μ„ ν‘œν˜„ν•˜κΈ° μœ„ν•΄ λ‘λ£¨λ§ˆλ¦¬ νœ΄μ§€λ₯Ό μ €λŸ°μ‹μœΌλ‘œ λ§λ„μ•ˆλ˜κ²Œ μ΄μƒν•˜κ²Œ 꽂은 κ²ƒμœΌλ‘œ 보면 λœλ‹€.

NaN