// 이름과 주소 속성을 갖는 객체 const person = { name: 'Lee', address: 'Suwon' }; console.log(person); // {name: "Lee", address: "Suwon"}
// 생성자 함수 function Circle(radius) { this.radius = radius; this.getArea = function () { // Math.PI는 원주율을 나타내는 상수다 return Math.PI * this.radius ** 2; }; } // 반지름이 1인 인스턴스 생성 const circle1 = new Circle(1); // 반지름이 2인 인스턴스 생성 const circle2 = new Circle(2); // Circle 생성자 함수는 인스턴스를 생성할 때마다 동일한 동작을 하는 // getArea 메서드를 중복 생성하고 모든 인스턴스가 중복 소유한다 // getArea 메서드는 하나만 생성하여 모든 인스턴스가 공유해서 사용하는 것이 바람직하다 console.log(circle1.getArea === circle2.getArea); // false console.log(circle1.getArea()); // 3.141592653589793 console.log(circle2.getArea()); // 12.566370614359172
// 생성자 함수 function Circle(radius) { this.radius = radius; } // Circle 생성자 함수가 생성한 모든 인스턴스가 getArea 메서드를 // 공유해서 사용할 수 있도록 프로토타입에 추가한다. // 프로토타입은 Circle 생성자 함수의 prototype 프로퍼티에 바인딩되어 있다. Circle.prototype.getArea = function () { return Math.PI * this.radius ** 2; }; // 인스턴스 생성 const circle1 = new Circle(1); const circle2 = new Circle(2); // Circle 생성자 함수가 생성한 모든 인스턴스는 부모 객체의 역할을 하는 // 프로토타입 Circle.prototype으로부터 getArea 메서드를 상속받는다. // 즉, Circle 생성자 함수가 생성하는 모든 인스턴스는 하나의 getArea 메서드를 공유한다. console.log(circle1.getArea === circle2.getArea); // true console.log(circle1.getArea()); // 3.141592653589793 console.log(circle2.getArea()); // 12.566370614359172
모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입, 즉[[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다
[[Value]]
을 갖지 않고, 접근자 함수[[Get]]
, [[Set]]
프로퍼티 어트리뷰드로 구성된 프로퍼티이다함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다
// 함수 객체는 prototype 프로퍼티를 소유한다 (function () {}).hasOwnProperty('prototype'); // true // 일반 객체는 prototype 프로퍼티를 소유하지 않는다 ({}).hasOwnProperty('prototype'); // false
생성자 함수로서 호출할 수 없는 함수,즉 non-constructor인 화살표 함수와 ES6 축약 표현으로 정의한 메서드는 prototype 프로퍼티를 소유하지 않으며 프로토타입도 생성하지 않는다
// 화살표 함수는 non-constructor다 const Person = name => { this.name = name; }; // non-constructor는 prototype 프로퍼티를 소유하지 않는다 console.log(Person.hasOwnProperty('prototype')); // false // non-constructor는 프로토타입을 생성하지 않는다 console.log(Person.prototype); // undefined // ES6의 메서드 축약 표현으로 정의한 메서드는 non-constructor다 const obj = { foo(){} }; // non-constructor는 prototype 프로퍼티를 소유하지 않는다 console.log(obj.foo.hasOwnProperty('prototype')); // false // non-constructor는 프로토타입을 생성하지 않는다 console.log(obj.foo.prototype); // undefined
모든 객체가 가지고 있는(Object.prototype으로부터 상속받은) __proto__ 접근자 프로퍼티와 함수 객체만이 가지고 있는 prototype 프로퍼티는 결국 동일한 프로토타입을 가리킨다. 하지만 이들 프로퍼티를 사용하는 주체가 다르다.
// 생성자 함수 function Person(name) { this.name = name; } const me = new Person('Lee'); // me 객체의 생성자 함수는 Person이다. console.log(me.constructor === Person); // true