JavaScript/함수

[JavaScript]함수의 프로토타입(prototype in function)

DevStory 2022. 7. 5.

함수의 프로퍼티

JavaScript에서 함수는 객체이지만, 일반 객체와는 다르게 함수 객체만의 표준 프로퍼티가 존재합니다.

 

이번 포스팅에서는 함수의 내부 프로퍼티인 [[Prototype]]와 다른 객체에 존재하지 않는 prototype 프로퍼티에 대해 설명합니다.

함수의 표준 프로퍼티인 length, name에 대해서는 아래 포스팅에서 자세하게 설명합니다.

 

[JavaScript]함수의 length, name 프로퍼티

함수는 특별한 객체 JavaScript에서 함수는 객체입니다. 객체와 마찬가지로 함수에는 프로퍼티와 함수가 존재하며, 함수를 변수, 배열, 객체에 할당하거나 다른 함수에 인수로 전달할 수 있습니다.

developer-talk.tistory.com

프로토타입에 대한 내용은 아래 포스팅에서 자세하게 설명합니다.

 

[JavaScript]프로토타입(Prototype)이란?

객체(Object) JavaScript의 프로토타입을 설명하기 전에 객체에 대해 살펴봅시다. JavaScript는 배열, 문자열 심지어 함수도 객체로 간주합니다. 다음 예제는 배열 생성 후 요소 추가, 삭제 그리고 요소

developer-talk.tistory.com


prototype 프로퍼티

모든 함수는 prototype 프로퍼티를 가지고 있습니다. 주의사항으로 prototype 프로퍼티는 함수에만 존재하며, 배열과 객체에는 존재하지 않습니다. 그리고 내부 프로퍼티인 [[Prototype]]과 다릅니다.

 

다음 예제를 실행해보면 prototype 프로퍼티가 함수에만 존재한다는 것을 확인할 수 있습니다.

function UserInfo(name, age) {
  this.name = name;
  this.age = age;
}

var arr = [1, 2, 3];
var obj = {
  name: 'Bob',
  age: 20
};

console.dir(UserInfo); // 함수
console.dir(arr);      // 배열
console.dir(obj);      // 객체

[실행 결과]

prototype 프로퍼티는 함수가 생성될 때, 만들어지며 두 개의 프로퍼티가 존재합니다. constructor 프로퍼티와 내부 프로퍼티인 [[Prototype]]가 있으며, constructor 프로퍼티는 자신과 연결된 함수를 가리킵니다.

즉, 함수가 생성될 때, JavaScript 엔진은 함수에 prototype 프로퍼티를 추가합니다.

함수의 prototype 프로퍼티는 함수의 프로토타입 객체를 가리킵니다.

함수의 프로토타입 객체에는 constructor 프로퍼티가 존재하는데, constructor 프로퍼티는 프로토타입 객체를 연결한 함수인 UserInfo를 가리킵니다.

정리하자면, 함수의 prototype 프로퍼티는 함수의 프로토타입 객체를 참조하고 함수의 프로토타입 객체의 constructor 프로퍼티는 연결된 함수를 참조합니다.

반응형

내부 프로퍼티 [[Prototype]]

내부 프로퍼티 [[Prototype]]은 프로토타입 객체를 가리킵니다.

 

내부 프로퍼티 [[Prototype]]은 객체, 배열에도 존재하며, 부모 역할을 하는 프로토타입 객체를 가리킵니다.

function UserInfo(name, age) {
  this.name = name;
  this.age = age;
}

var arr = [1, 2, 3];
var obj = {
  name: 'Bob',
  age: 20
};

console.dir(UserInfo); // 함수
console.dir(arr);      // 배열
console.dir(obj);      // 객체

[실행 결과]

출력 결과에서 내부 프로퍼티 [[Prototype]]을 확인할 수 있습니다. 배열의 부모 역할을 하는 프로토타입 객체는 Array이며, 객체의 부모 역할을 하는 프로토타입 객체는 Object입니다.

 

함수 객체의 부모 역할을 하는 프로토타입은 Function.prototype 객체이며, Chrome에서는 ƒ ()라고 명명하고 있습니다.

ƒ () 역시 함수이므로 함수의 특별한 프로퍼티인 apply, arguments, bind, call 등 함수 객체의 프로퍼티가 존재한다는 것을 확인할 수 있습니다.


prototype과 [[Prototype]]

내부 프로퍼티인 [[Prototype]]는 부모 역할을 하는 프로토타입 객체를 가리키며, 함수 객체에 존재하는 prototype 프로퍼티는 함수가 생성자로 사용될 때 생성된 객체의 부모 역할을 하는 프로토타입 객체를 가리킵니다.

 

다음 예제를 Chrome 개발자 도구에서 실행 후 함수의 prototype 프로퍼티와 생성자 함수로 생성된 객체의 내부 프로퍼티인 [[Prototype]]를 살펴봅시다.

function UserInfo(name, age) {
  this.name = name;
  this.age = age;
}

var obj = new UserInfo('Bob', 20)

console.dir(UserInfo);
console.dir(obj);

[실행 결과]

실행 결과를 확인하면, 함수의 prototype 프로퍼티와 생성자 함수로 생성된 객체의 [[Prototype]]은 같은 프로토타입 객체를 가리키고 있다는 것을 알 수 있습니다.

 

아래 그림은 prototype 프로퍼티에서 설명한 그림에서 생성자 함수로 생성된 객체 obj가 추가됩니다.

즉, 생성자 함수로 생성된 객체의 내부 프로퍼티 [[Prototype]]은 생성자 함수의 프로토타입 객체를 가리키므로 프로토타입 객체의 프로퍼티를 접근할 수 있습니다.

 

다음 예제는 생성자 함수로 생성된 객체가 프로토타입 객체의 생성자(constructor) 프로퍼티를 호출합니다.

function UserInfo(name, age) {
  this.name = name;
  this.age = age;
}

var obj = new UserInfo('Bob', 20)

// 호출할 때는 [[Prototype]]가 아닌 __proto__로 호출합니다.
console.dir(obj.__proto__.constructor);

[실행 결과]

그리고 생성자 함수의 prototype 프로퍼티와 생성자 함수로 생성된 객체의 내부 프로퍼티 [[Prototype]]는 동일한 프로토타입 객체를 가리킨다는 것을 동치 연산자로 확인할 수 있습니다.

function UserInfo(name, age) {
  this.name = name;
  this.age = age;
}

var obj = new UserInfo('Bob', 20)

console.log(obj.__proto__ === UserInfo.prototype); // true
console.log(obj.__proto__.constructor === UserInfo.prototype.constructor); // true
반응형

댓글