[JS] 객체와 함수와 클래스

UI SEOK YU·2023년 1월 4일
0

JavaScript

목록 보기
1/6
post-thumbnail

nestJS로 개발 하던 중, 싱글 톤 패턴을 알게 되었고 하나의 인스턴스만 생성하는 것을 알게되었다. 각각의 모듈이 어떤 방식으로 의존성이 주입되어 인스턴스가 생성되는지 연달아 궁금해졌다. JS에서 클래스는 생성자 함수를 활용한다고 알고 있는데, 정확한 작동형태가 머릿속에 그려지지 않았다. 자바스크립트의 객체-함수-클래스의 관계에 대해 탐구해 봐야겠다는 생각이 들었다.

스터디 발표영상 (유튜브)
📺 https://www.youtube.com/watch?v=X9Dtj4crnRM


0. 들어가며

  • 객체, 함수, 클래스에 관하여, 이 세 개의 개념이 어떤 관계로 존재하는 것인지 명확하게 알아야 할 필요성을 깨달았다.

  • 내가 객체, 함수, 클래스를 무작정 떠올리면 위와 같은데
    단순히 키-값 형태의 객체,
    뭔가를 넣으면 돌려서 뭔가가 나오는 함수,
    비슷한 것을 찍어내기 위해 만든 틀인 클래스.. 정도이다.

  • 그 상태에서 위 두 문장을 만났다.
    두 문장은 참이다.
    근데 왜 참인지 모르겠다.
    설명할 수가 없는게 답답해서 공부하기 시작했다.
    그냥 단순 개념을 외우는게 아니라 내 머리속에서 지도가 그려져야 했다.

1. 객체

  • 객체를 알기 전에 먼저 알아야 할 선행 개념들이 있다.

  • ? 말 그대로 '값' 이라서 생각해본적이 없었다.
    하지만 정의를 찾아보니,

  • 자바스크립트에서는 표현식평가된 것을 값으로 정의했다.

  • 그럼 표현식은 뭔데?

  • 표현식은 평가 가능한 문이라고 한다.
  • 그럼 평가는 뭐고 은 정확히 무엇을 의미하는가..

  • 은 문법적으로 뜻을 지니는 (더이상 쪼갤 수 없는) 문장/식 이고,

  • 평가는 그 문장/식이 계산되어서 메모리에 저장되는 것을 의미했다.

  • 사실 비슷한 단어가 계속 반복되서 말장난 하는 것 같지만, 구조를 그려보면 다음과 같다.

  • 가장 상위 개념에 이 있고, 평가 가능여부에 따라 나뉜다.
  • 평가가 불가능한 문은 선언문, 반복문, 조건문 등이 있고,
  • 평가가 가능한 문이 우리가 말하는 표현식 인 것이다.
  • 표현식은 평가가 가능한 문이므로, 평가를 하면 비로소 이 된다.

  • 표현식에는 다양한 형태가 있다. 위 예시들 뿐만아니라 무한한 형태의 표현식이 존재할 것이다.
  • 그 중, 대표적인 두 개의 형태만 예시로 들어보겠다.

  • 'abc'라는 표현식이 평가될 때,
    메모리에 a 변수가 할당되고, undefined로 초기화가 된다.
    그 후, 'abc'를 넣은 메모리의 주소를
    a로 할당(=) 하며 주소값을 가지게 된다.

  • 즉, a(라는 식별자가 붙은 변수)가 가리키는 것은 'abc'이다.

  • 그러면 1,2,3 이나 'abc' 같은형태가 아닌, 자료구조는 어떻게 될까.
    객체를 담기 위한 메모리를 지정하고, 객체안에 있는 변수들(name, age)이 담길 메모리도 지정해 준다.
    객체가 담길 메모리에는 최종적으로 객체의 주소범위만 담기게 된다.

  • b가 가리키는 것은 객체 자체가 아닌, '객체를 가리키는 주소의 값' 이 된다.

  • 잘 생각해보면 어렵지 않다. 자료구조는 상자 안에 상자가 있는 형태니, 저런식으로 주소를 꼬리에 꼬리를 무는 형태가 되는게 당연하다.

  • a는 'abc'를 가리켰는데,
    b는 @7104 주소를 가리킨다.
    똑같이 var ### = 000 형태로 할당했는데
    변수가 가리키는 값의 형태가 다르다.

  • 이 처럼 값은 이분법적으로 나타낼 수 있다.
    원시타입인 것과 그 외 주소타입로 표현된 것.
  • 그 중에서 우리는 주소로 표현 된 것을 객체타입(참조타입) 이라고 하게 된 것이다.

  • 처음 그렸던 구조도에 방금 것을 추가해 보면,
    객체가 어떤 위치에서 등장했는지 파악할 수 있다.

  • 이제 함수를 보자.


2. 함수

  • 함수는 다양한 형태로 나타낼 수 있다.
    그 중 대표적인 두 개만 들고 와 봤다.

  • 우리가 여기서 주목해야할 부분은,
    자바스크립트에서는 함수가 표현식으로 사용될 수 있다는 것이다.

  • 표현식은 평가가 되어 값 이 되는 존재였다.
  • 함수 또한 평가되서 변수에 원시값이 아닌 주소가 담기므로,
  • 함수객체타입이라고 할 수 있다.

  • 함수는 자바스크립트가 설계 될 때 일급객체로 취급되도록 되어있다. 4가지 조건을 만족하면 일급객체라고 하는데,

  • 함수의 결과 값만 일급으로 다루는게 아니라, 함수 그 자체를 일급으로 다룬다는 점이 중요하다.

  • 함수 내부에는 [[call]] 이라는 내장메서드가 포함되어 있는데, 이 메서드는 일반 객체에서는 존재하지 않는다. 함수가 호출 될 때 사용되는 장치이다.

  • 즉, 객체 중에서 호출이 가능한 존재들을 모아 분류한 것이 함수이다.

  • 함수가 일반객체와 구분되는 것은 다양한 것들이 있지만, 일단 함수를 이렇게 가지치기를 할 수 있구나 라고 생각하면 된다.

  • (실제로 함수가 생성될 때는, Funcion 생성자 함수에 의해 생성되며, 이는 다른 생성자로 만들어진 객체들과 내장된 내용이 다르다.)

  • 여기까지 함수가 어떤 부류인지 알아보았다.
    이어서 클래스를 보자.


3. 클래스

  • 클래스를 바로 들어가지는 않고, 아래 그림을 먼저보자.
    자바스크립트를 공부하다 보면 언젠가 한 번은 봤던 구조이다.

  • 모든 객체(인스턴스)는 생성자 함수로부터 만들어지며 (리터럴로 만들어도 암묵적으로 생성자 함수를 통해 구현된다)
  • 해당 객체는 프로토타입을 가져서 부모의 프로퍼티를 참조할 수 있다.
  • 생성자 함수프로토타입은 1:1의 상호 참조구조를 갖는다.

  • 실제로 코드로 보아도 그렇다.
  • 근데 저기 물음표 친 prototype은 무엇인가?
    [[prototype]] 과는 다른 존재인 것 같은데..

  • 저 삼각형의 구조를 하나 더 그려보면 쉽게 알 수 있다.

  • 생성자 함수로 만들어진 함수가, '또 다른 어떤 인스턴스' 의 생성자 함수가 될 때, 사용되어야 할 프로토 타입 객체인 것이다. (빨간색 표시)

  • 여기서 알 수 있는 것은,

  • " 생성자 함수함수에 포함된다. " 보단,
    " 모든 함수는 잠재적 생성자 함수 " 라는 것이 더 정확한 표현이다.
    (단, 내부에 [[construct]] 가 있어야만 함)

  • 예시를 보자.

  • 원을 만들어 내는 함수를 정의했다.
    반지름이 있고, 지름을 구하는 함수가 내포되어 있다.
    인수를 전달하여 new 로 인스턴스를 생성할 수 있다.

  • 나는 생성자 함수를 만든 것이 아니라,
    함수를 만들어 두고, new를 붙여서 생성자 함수로 활용한 것이다.

< 참고 >

  • 생성자 함수 로 사용될 때의 this 는 새로 생성하는 객체를 가리킨다.
    위 처럼 생성자 함수로 new Circle(5) 를 하면, 새로운 Circle 인스턴스의 반지름이 5 가 된다.
  • 반면에 일반 함수 로 실행한다면 this는 참조하는 객체가 없으므로 전역객체를 가리키게 된다.
    따라서 그냥 Circle(5)를 해버리면 전역변수 radius가 생성되고 그 값이 5가 되어버린다.

  • 그런데 여기서 모습을 조금만 바꾸면 클래스가 된다.

  • 아까 보았던 삼각형 구조에서, 초록색 부분이 클래스가 되는 것이다.

  • 클래스를 만들고 내부를 보면,
    typeof는 function으로 나오며,
    프로퍼티로 prototype 객체를 가지고 있다.

  • 실제로 클래스가 평가 될 때에도, 생성자 함수 형태로 평가가 된다.

  • 클래스의 모든 역할을 생성자 함수로 구현이 가능했다.

  • 클래스는 사실 자바스크립트에서 필요없는 것 처럼 보이기도 한다.

  • 클래스 작동원리를 파헤쳐 보면, 모두 프로토타입 형태로 구동된다. (ex : 상속 -> 프로토타입 체인 )

  • 다만 객체지향의 직관성을 높여서 간결하고 명료한 코드작성을 가능하게 한다.

  • 결국 클래스는 생성자 함수의 다른 형태라고 보면 되겠다.


4. 정리

  • 다시 처음으로 돌아와서, 에서 부터 시작한 구조를 클래스까지 그려보면 위와 같다.
  • 평가가 가능한 문을 표현식이라고 하며, 표현식은 평가가 되면 이 된다.
  • 은 참조하는 데이터의 유형에 따라 원시값객체로 분류된다.
  • 객체는 호출여부에 따라 일반객체함수로 나뉜다.
  • 함수 중, 생성자 함수를 다른 형태로 표현한 것이 클래스 이다.
  • 이제 좀 직관적으로 관계가 그려진다.


따라서 클래스함수다.
그리고 함수객체다.

끝.

0개의 댓글