프로그래밍 언어를 배우다 보면

서로 비슷해 보이지만 실제로는 전혀 다른 개념들을 자주 마주하게 됩니다.

이번 글에서는 자바스크립트와 파이썬에서 자주 사용되는 두 개념, null vs None

그리고 this vs self를 비교해보려 합니다.


 

목차

    1. null과 None
      1. 내부 동작 차이
      2. 자바스크립트의 설계오류(null)
    2. this와 self
      1. this는 묵시적, self는 명시적

1. null과 None

프로그래밍을 하다 보면 개발자가 의도적으로 "값이 없다"는 상황을 표현해야 할 때가 많습니다.

자바스크립트에서는 null, 파이썬에서는 None 이라는 키워드를 사용해 이를 나타내는데요,

 

두 언어 모두 "값이 없음"을 의미하지만,

내부 구현 방식과 메모리 관리 방식에서는 뚜렷한 차이가 있습니다.

 

1) 내부 동작 차이

자바스크립트의 null은 내부적으로 참조할 객체가 없다는 의미를

메모리 주소 0을 가리켜서 표현합니다.

참고로 null은 개발자가 명시적으로 지정하는 것이고,

undefined는 시스템(또는 JS엔진)이 "초기화되지 않은 값"을 자동으로 부여할 때 사용합니다.

 

null을 비교할 때는 반드시 ===(엄격한 비교)를 사용하는 것을 권장합니다.

== 연산자는 타입 변환을 허용하기 때문에 예기치 않은 결과를 초래할 수 있습니다.

 

typeof null을 실행하면 null이 아닌 object가 결과로 나오는데

이는 자바스크립트의 설계 오류로 뒤에서 다시 살펴보겠습니다.

 

Python의 None은 메모리에 실제 존재하는 단일(Singleton) 객체입니다.

프로그램이 시작될 때 하나의 None 객체가 생성되고,

코드 내에서 사용되는 모든 None은 이 동일한 객체를 참조합니다.

 

모든 None이 단일 객체를 참조하므로, 메모리 상에서도 매우 효율적으로 관리됩니다.

None은 값이 아니라 객체이므로, 비교할 때는 is 연산자를 사용하는 것이 권장됩니다.

is는 메모리 주소를 비교하여 같은 객체인지를 확인합니다.

type(None)을 출력해보면 'NoneType'이 반환됩니다.

 

2) 자바스크립트의 설계오류(null)

자바스크립트의 null 타입 관련 설계 오류는 꽤 유명합니다.

위에서 말한것처럼 null은 '참조할 객체가 없음'을 의미합니다.

 

내부적으로 메모리 주소 0을 참조하는 null 포인터로서 표현하는데

이는 저수준 언어(c언어)의 설계 방식을 참고하여 만들어졌기 때문입니다.

let obj = null;
//힙 : 0(null)
//스택 : 0번지 메모리 주소(null 포인터)

 

 

그럼 왜 typeof 연산자를 사용하면 object 가 나오는 것일까요?

자바스크립트 엔진은 typeof 연산자를 사용할 때 다음과 같은 로직으로 동작합니다.

1. 해당 값의 메모리 주소 확인
2. 메모리 주소가 존재하면 이를 Object 타입으로 인식
3. null은 초기 설계에서 0번지 메모리 주소를 참조하기 때문에, 메모리 주소가 존재한다고 판단
4. 따라서 typeof null의 결과는 "object"를 반환

 

 

자바스크립트가 발전하면서 대형 어플리케이션에서도 자바스크립트가 사용되면서 설계 오류가 드러났지만

이미 많은 곳에서 typeof null을 object로 처리하고 있었기 때문에

이를 수정하면 기존 코드가 깨지는 레거시 호환성 문제가 발생하여

해당 오류는 수정되지 않고 그대로 유지되었습니다.

typeof null //object
typeof undefined //undefined

nul == undefined //true
nul === undefined //false

 

 

2. this와 self

1) this는 묵시적, self는 명시적

프로그래밍 언어에서 객체나 인스턴스 자신을 참조할 때 사용하는 키워드는 자주 등장합니다.
자바스크립트에서는 this, 파이썬에서는 self를 사용합니다.

 

this (JavaScript)

  • this는 자바스크립트 객체 메서드나 함수 안에서 자기 자신을 참조하는 키워드입니다.
  • 묵시적으로 바인딩되며,
    호출 방식에 따라 this가 가리키는 대상이 달라질 수 있습니다.
const example = {
    value: 10,
    show: function() {
        console.log(this.value);
    }
};

example.show(); // this는 example 객체를 가리킴
  • 하지만 호출 문맥(call context)에 따라 this가 달라지기 때문에,
    헷갈릴 여지가 많습니다.

 

지난번 포스팅에서는 변수가 메모리에 저장될 때 스택 프레임이 생성되고,
그 안의 실행 컨텍스트(Execution Context)this 바인딩 정보가 포함된다고 설명했습니다.

이는 자바스크립트의 this가 묵시적으로 바인딩되는 특성을 반영한 구조입니다.

반면, 파이썬에서는 self를 메서드의 첫 번째 인자로 명시적으로 전달하기 때문에,
별도의 this 바인딩 정보를 스택 프레임에 저장할 필요가 없습니다.
(파이썬의 스택 프레임에는 메서드 인자와 지역 변수 정보가 저장되지만, self는 항상 개발자가 명시적으로 다루어야 합니다.)

 

*지난번 포스팅 : https://sol-aftercoding.tistory.com/entry/KDA-2%EC%9D%BC%EC%B0%A8-416

 

[KDA] 변수는 왜 스택에, 객체는 힙에 저장될까?

최근 KDA(키움 디지털 아카데미)를 수강하면서,그동안 가볍게만 다뤘던 파이썬을 처음으로 제대로 배울 기회가 생겼습니다. 저는 주로 자바스크립트를 사용해왔기 때문에,파이썬을 배우면서 문

sol-aftercoding.tistory.com

 

 

self (Python)

  • self는 파이썬 클래스 메서드 안에서 인스턴스를 가리키는 키워드입니다.
  • 명시적으로 메서드의 첫 번째 인자로 작성해야 합니다.
  • 모든 인스턴스 메서드는 첫 번째 인자로 self를 받아야 하며,
    이 self를 통해 인스턴스의 속성이나 다른 메서드에 접근합니다.
  • 규칙이 엄격하고 명시적이기 때문에,
    self가 무엇을 가리키는지 항상 명확합니다. 혼동이 거의 없습니다.
class Example:
    def __init__(self, value):
        self.value = value

    def show(self):
        print(self.value)

 

참고자료

- 모던 자바스크립트 딥다이브

- KDA : 파이썬 프로그래밍(송치오 강사님)

 

최근 KDA(키움 디지털 아카데미)를 수강하면서,
그동안 가볍게만 다뤘던 파이썬을 제대로 배울 기회가 생겼습니다.

 

저는 주로 자바스크립트를 사용해왔기 때문에,
파이썬을 배우면서 문법적인 부분뿐만 아니라 언어 내부의 동작 방식에서도
자바스크립트와의 공통점과 차이점을 많이 느낄 수 있었고, 꽤 흥미로웠습니다.

 

그래서 이번 포스팅에서는 두 언어의 차이점 중에서도
"변수는 왜 스택에, 객체는 힙에 저장될까?" 라는 주제를 중심으로,
변수와 메모리 구조에 대해 비교 및 정리해보려고 합니다.


 

목차

    1. 자바스크립트의 자료형과 메모리 저장 방식
    2. 변수는 왜 스택에, 객체는 힙에 저장될까?
      1. 스택과 힙의 차이
      2. 스택이 CPU 캐시와 잘 맞는 이유 
      3. 메모리 계층 구조 시각화
    3. 파이썬에서는 모든 변수가 객체다
    4. 자바스크립트와 파이썬의 함수 호출 시 메모리 흐름 비교

 

1. 자바스크립트의 자료형과 메모리 저장 방식

자바스크립트에서는 기본형(Primitive)과 참조형(Reference) 두 가지 주요 타입이 있습니다.

 

1) 기본형 타입 (Primitive Type)

  • number, string, boolean, null, undefined, symbol, bigint
  • 값 자체가 스택에 저장됨.
  • 변수는 실행 컨텍스트에 키/값 형식인 객체로 등록되어 관리됨.
var data = 3

// data(식별자): 스택에 저장됨
// 3(값): 고정 크기의 값이므로 스택에 함께 저장됨

 

2) 참조형 타입 (Reference Type)

  • object, array, function, map, set, date, class 등
  • 스택에는 참조값(주소)만 저장되고, 실제 값은 힙(heap)에 저장됨.

 

왜 기본형과 같은 변수는 스택에, 참조형과 같은 객체는 힙에 저장될까?

기본형 타입은 고정된 크기이며, 메모리 참조가 필요 없기 때문에 스택에 저장됩니다.
참조형은 데이터 크기가 가변적이라 스택처럼 고정된 메모리 구조에 적합하지 않기 때문에
힙 영역에 저장됩니다.

 

 

2. 변수는 왜 스택에, 객체는 힙에 저장될까?

1) 스택과 힙의 차이

항목 스택(Stack) 힙(Heap)
메모리 구조 선입후출 (LIFO), 계단식 구조 자유로운 크기 할당, 트리 구조
속도 빠름 (고정된 순서로 할당/해제됨) 느림 (GC 등 관리 필요)
메모리 크기 작음 (고정 크기) 큼 (운영체제에서 크게 확보됨)
할당 방식 컴파일 타임에 할당 런타임에 동적 할당
사용 목적 고정 크기 변수, 함수 호출 프레임 크기 유동적인 데이터 저장 (객체 등)
해제 방식 함수 종료 시 자동 해제 가비지 컬렉터(GC)가 추적 후 해제

 

정리하자면,
스택(stack)은 빠른 접근이 가능하고, 함수가 끝나면 자동으로 메모리가 해제된다는 특징이 있습니다.

CPU 캐시와 잘 맞기 때문에 성능적으로 유리합니다.
반면 힙(heap)"어디에나" "얼마든지" 저장할 수 있는 유연성을 가지지만,
메모리 할당과 해제가 복잡하고, 이를 관리하기 위해 GC(가비지 컬렉션)가 필요합니다.

 

비유하자면,

  • 스택책상 위에 차곡차곡 쌓아두는 포스트잇 같고,
  • 방 안에 자유롭게 던져놓은 상자들과 같습니다.

 

2) 스택이 CPU 캐시와 잘 맞는 이유

스택이 CPU 캐시 hit률을 높여주는 이유

특징 설명
연속된 메모리 구조 공간 지역성 → 인접 데이터 캐시에 같이 올라감
짧은 생명주기, 반복 접근 시간 지역성 → 자주 쓰는 데이터 반복 사용
작고 고정된 크기 캐시에 올리기 적합한 사이즈

⇒ 결과적으로 성능 및 속도↑

 

3) 메모리 계층 구조 시각화

 

예를 들어보자면,

함수가 호출되면 그 함수 전용의 스택 프레임(Stack Frame)이 스택에 생성되고,

해당 함수 안에서 선언된 모든 지역 변수들은 이 프레임 안에 묶여 저장됩니다.

함수 실행이 끝나면, 프레임 전체가 pop되어 메모리에서 사라집니다.

 

 

3. 파이썬에서는 모든 변수가 객체다

파이썬은 자바스크립트와는 다른 변수 저장 로직을 가지고 있습니다.

 

  • x = 10 코드 실행 시:
    1. 10이라는 정수 객체(int)가 먼저 힙(heap)에 생성됨
    2. 이름 x가 현재 네임스페이스(scope)에 등록됨
    3. x는 10 객체를 참조하게 됨

⇒ 즉, 파이썬에서 변수는 값이 아닌 객체를 가리키는 이름일 뿐입니다.

영역 설명
스택(Stack) 함수 호출 시 생성되는 프레임 (지역 변수의 이름과 참조 정보 저장)
힙(Heap) 실제 객체 데이터(숫자, 리스트, 인스턴스 등)를 저장

 

또한 네임스페이스는 스택 프레임의 일부로 존재하며,

지역 변수 정보(이름 → 객체 참조 관계)가 네임스페이스 안에 저장되는 것입니다.

 

 

4. 자바스크립트와 파이썬의 함수 호출 시 메모리 흐름 비교

함수 호출 시 스택 프레임이 생성된다는 것은 같지만,

생성되는 스택 프레임의 구성은 두 언어가 다릅니다.

 

자바스크립트에서 함수가 호출될 때,

스택 프레임에는 함수 코드와 실행 컨텍스트가 생성됩니다.

실행 컨텍스트는 변수나 함수의 초기 상태를 관리하는 Variable Environment,

실질적으로 변수의 스코프를 관리하는 Lexical Environment, 그리고 this 바인딩 정보 등을 포함합니다.

 

반면 파이썬에서는 함수 호출 시,

스택 프레임에 리턴 주소와 딕셔너리 구조의 네임스페이스가 함께 생성됩니다.

네임스페이스에는 지역 변수 이름과 참조 정보를 관리하며,

모든 변수는 힙에 존재하는 객체를 참조합니다.

 

 

참고자료

- 모던 자바스크립트 Deep Dive

- KDA : 파이썬 프로그래밍(송치오 강사님)

+ Recent posts