두가지 모두 javascript에서 프로토 타입에 접근하는데 사용되는 메커니즘이다. 하지만 사용 방법과 결과적인 동작에 차이가 있는데 아래 코드를 통해 차이점을 알아보자
예시 1
function Parent(name,age){
this.name = name;
this.age = age;
}
Parent.prototype.greet = function(){
console.log(this.name+"! hello")
}
var child = new Parent("홍길동",12);
console.log(child.__proto__ === Object.getPrototypeOf(child)) //출력 :true
두 가지 모두 자신이 바라보고있는 프로토타입을 가리킨다.
예시 2
// 부모 객체
var parent = {
greet: function() {
console.log('Hello from parent');
}
};
// 자식 객체
var child = {};
// __proto__를 사용하여 프로토타입 설정
child.__proto__ = parent;
// Object.getPrototypeOf()를 사용하여 프로토타입 확인
var proto = Object.getPrototypeOf(child);
// 결과 확인
console.log(proto === parent); // true
proto.greet(); // Hello from parent
__proto__
는 프로토타입을 설정할 수 있다.
실제로 Object.getPrototypeOf()
를 통해 확인한 프로토타입이 parent와 동일한것을 보면 알수 있다.
javascript에서 생성하는 메서드이다. 이 메서드를 사용하면 새로운 객체를 생성하고 해당 객체의 프로토 타입을 지정할 수있다.
// 프로토타입 객체
var personPrototype = {
greet:function(){
console.log("Hello, "+this.name+"!");
}
}
// 새로운 객체 생성
var person = Object.create(personPrototype);
// 프로토 타입 객체의 속성 설정
person.name = "Alice";
// 객체의 메서드 호출
person.greet(); //Hello, Alice!
// 프로토타입 객체
var personPrototype = {
greet: function() {
console.log('Hello, ' + this.name + '!');
}
};
// 새로운 객체 생성 및 프로퍼티 설정
var person = Object.create(personPrototype, {
name: {
value: 'Alice', //값
writable: true, //변경 가능한지 여부
enumerable: true, //열거 가능한지 여부
configurable: true //프로퍼티의 설정을 변경할 수 있는지 여부
},
age: {
value: 25,
writable: false,
enumerable: true,
configurable: false
}
});
// 객체의 메서드 호출
person.greet(); // Hello, Alice!
// 프로퍼티 값 변경 시도
person.name = 'Bob'; // 가능
person.age = 30; // 불가능
// 프로퍼티 열거
for (var prop in person) {
console.log(prop + ': ' + person[prop]);
}
// 열거된 프로퍼티
// "name: Bob"
// "age: 25"
// "greet: function() {
// window.runnerWindow.proxyConsole.log('Hello, ' + this.name + '!');
// }"
ES5는 객체의 프로토타입을 가져오기 위한 표준 API로 Object.getPrototypeOf
를 도입했지만, 많은 자바스크립트 엔진들은 이미 동일한 목적으로 __proto__
프로퍼티를 제공해 왔다.
그렇다고 모든 프로퍼티가 Object.getPrototypeOf
를 지원하는것도 아니다. 실행 환경들은 null 프로토타입을 가지는 객체를 ㅅ로 다르게 처리한다.
어떤 실행 환경에서 __ proto __
는 Object.prototype
을 상속하고 , 따라서 null프로토타입을 가지는 객체는 특별한 __ proto __
프로퍼티를 가지지 않는다.
var empty = Object.create(null); //프로토 타입이 없는 객체
"__ proto __" in empty; //false; => empty라는 객체에 prototype프로퍼티가 있는지 확인한다.
이것이 다른 몇몇 환경에서는 다음과 같이 처리된다.
var empty = Object.create(null); //프로토 타입이 없는 객체
"__ proto __" in empty; //true; => empty라는 객체에 prototype프로퍼티가 있는지 확인한다.
__ proto__
는 모든 객체를 어지럽히는 많은 버그를 초래한다. 때문에 Object.getPrototypeOf
를 사용하는 것이 좋다. 혹은 __ proto __
를 사용해 Object.getPrototypeOf
를 구현하는 방법은 다음과 같다.
if(typeof Object.getPrototypeOf === 'undefined'){
Object.getPrototypeOf = function(obj){
var t = typeof obj;
if((!obj || (t !==' Object" && t !== "function)){
throw new TypeError("not an object");
}
return obj.__proto__;
};
}
prototype
을 반환한다.__ proto __
프로퍼티를 사용하기 보다 표준을 준수하는 Object.getPrototypeOf()
를 사용하자__ proto__
를 지원하고 ES5를 지원하지 않는 실행 환경에서 Object.getPrototypeOf
를 구현하자