ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수 호출구조
    JavaScript 2020. 10. 5. 15:32

    자바스크립트에서의 함수 호출 구조에 대해서 다룰 것 이다.

    위의 자료를 보면 이상한 부분이 있을 것 이다. 

    변수 value에 분명 new String 연산자를 통해 문자열 123을 가지는 값을 할당하고 거기서 다시 String 객체의 toString 매서드를 호출 한 것이다. 왜 자바스크립트에서는 문자열 객체에 문자열로 바꾸어 주는 매서드를 넣어 둔 것일까 ? 라는 의문이 생길 것 이다.

    위의 의문을 해결하기 위해서는 자바스크립트가 빌트인 된 객체의 내장 함수(매소드)를 호출 할 때 어떻게 호출하는 구조 인지 이해해야 한다.

    자바스크립트는 매소드 호출시 해당 객체의 동일한 Level 의 프로퍼티에서 호출하는 매소드를 찾게 되며 이때 해당 매소드가 없을 경우 해당 Level 의 __proto__ 라는 프로퍼티의 참조에 대해서 재탐색 하는 구조를 띈다. 쉽게 말해 호출한 매소드가 없을경우 계속해서 __proto__ 에 연결 된 참조 객체에서 찾는다는 의미이다. 

    이때 __proto__ 는 Javascript 에서 제공하는 빌트인 자료의 prototype 객체를 의미한다. 따라서 { __proto__ : String.prototype(주소) } 와 같이 빌트인 된 자료형 객체의 참조를 벨류 값으로 가지고 있다.

     위의 자료는 String 객체의 인스턴스인 value가 가지는 String 객체의 prototype을 출력한 모습이다. 오브젝트 형태로 사용할 수 있는 내장 매소드를 확인 할 수 있으며 만약 사용자가 length 매소드를 호출 한다면 자바스크립트 엔진은 내부적으로 다음과 같은 과정을 거치게 된다.

    1. value 변수에 담긴 데이터 Type 추론
    2. 추론한 데이터 Type에 맞는 객체의 인스턴스를 생성
    3. 해당 인스턴스의 사용자가 호출한 length 매소드 확인
    4. value 인스턴스의 프로퍼티 값으로 length : 3 라는 프로퍼티가 존재
    5. 3 출력

    위와 같은 과정을 거치게 된다. 그렇다면 value 인스턴스의 프로퍼티 중 length 가 없다면 어떻게 될까 ?

    정답은 __proto__ 라는 프로퍼티의 하위 프로퍼티에 접근하여 length 라는 매소드를 찾는 다는 것이다.

    따라서 value 안에 __proto__ 프로퍼티 안의 length 프로퍼티 key의 값을 반환하게 된다.

     

    이제 다시 처음으로 돌아가서 왜 ? String 오브젝트 안에 toString 이라는 매소드가 존재하는지 생각해 보자 만약 String 오브젝트 안에 toString 이라는 매소드가 없다고 가정해 보자 어떠한 일이 벌어 질거 같은가 ?

    1. String 인스턴스의 프로퍼티 중 toString 매소드 확인
    2. String 객체에는 toString이 존재하지 않기 때문에 하위의 __proto__ 프로퍼티 확인
    3. 하위의 __proto__ 프로퍼티 중 toString 확인 매소드 실행 후 반환

    위와 같은 동장이 내부적으로 이루어질 것 이다. 그렇다면 String 객체의 __proto__ 안에 있는 __proto__ 프로퍼티를 확인해 보도록 한다.

       위와 같이 String(인스턴스).__proto__.__proto__ 의 값은 Object 객체를 가진다. 이말은 즉 String 객체에 toStrong 매서드가 없어 질 경우 그보다 하위의 __proto__ 라는 Key 값에 접근하게 되는데 이때 __proto__라는 프로퍼티의 벨류 값은   Object 객체이다. 따라서 Object 객체의 프로퍼티 중 toString 매소드 찾아 해당 매소드를 반환하게 된다. 따라서 다음과 같은 값이 반환 된다. 

    [object Object] 와 같은 값이 나오게 된다. 이는 value.__proto__ 까지는 String 객체를 상속 받은 매서드와 속성이 있으며 그 하위의 __proto__에는 Object 객체를 상속 받은 매소드와 속성이 존재하며 현재 접근한 value.__proto__.__proto__는 Object 객체의 프로토타입에 정의 되어있는 toString 매소드를 호출하기 때문에 발생하는 일 이다.

    + Object 객체의 Prototype에 정의 되어있는 매소드 toString은 선택한 요소의 정보를 보여준다.                                   EX -> var value = new String(123) 에서 value.__proto__.__proto__.toString 은 value 인스턴스의 정보를 나타내 준다     따라서 인스턴스 임을 나타내 주는 object 와 해당 데이터의 타입을 나타내 주는 Object(new 연산자를 사용한 인스턴스를 생성했기 때문) 가 출력된다.

    따라서 이러한 문제를 막기 위해 String 객체의 매소드로 toString 이라는 매소드를 추가함으로써 그보다 하위의 __proto__ 까지 접근하지 못 하게 한다.  

    'JavaScript' 카테고리의 다른 글

    Built-in Object (Object 자료형)  (0) 2020.10.08
    JavaScript 의 Object 종류와 JS의 플랫폼  (0) 2020.10.06
    Built in object 의 생성 (인스턴스)  (0) 2020.10.05
    Built-in object 란 ? (인스턴스)  (0) 2020.09.23
    Built-in 이란 ?  (1) 2020.08.17

    댓글

Designed by Tistory.