-
함수 호출구조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 매소드를 호출 한다면 자바스크립트 엔진은 내부적으로 다음과 같은 과정을 거치게 된다.
- value 변수에 담긴 데이터 Type 추론
- 추론한 데이터 Type에 맞는 객체의 인스턴스를 생성
- 해당 인스턴스의 사용자가 호출한 length 매소드 확인
- value 인스턴스의 프로퍼티 값으로 length : 3 라는 프로퍼티가 존재
- 3 출력
위와 같은 과정을 거치게 된다. 그렇다면 value 인스턴스의 프로퍼티 중 length 가 없다면 어떻게 될까 ?
정답은 __proto__ 라는 프로퍼티의 하위 프로퍼티에 접근하여 length 라는 매소드를 찾는 다는 것이다.
따라서 value 안에 __proto__ 프로퍼티 안의 length 프로퍼티 key의 값을 반환하게 된다.
이제 다시 처음으로 돌아가서 왜 ? String 오브젝트 안에 toString 이라는 매소드가 존재하는지 생각해 보자 만약 String 오브젝트 안에 toString 이라는 매소드가 없다고 가정해 보자 어떠한 일이 벌어 질거 같은가 ?
- String 인스턴스의 프로퍼티 중 toString 매소드 확인
- String 객체에는 toString이 존재하지 않기 때문에 하위의 __proto__ 프로퍼티 확인
- 하위의 __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