• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

__proto__ 로 하지 않는 이유가 따로 있을까요??

20.07.30 04:14 작성 조회수 182

2

안녕하세요!! 너무 좋은 강의 잘 보고 있습니다.

bridge를 통해서 static method, variable과 연결고리를 끊는 부분에 대해서 질문 드립니다.

<1>

function Person() {
	this.staticBye = function() {
		console.log("bye");
	}
}
Person.prototype.prototypeHi = function() {
	console.log("hi");
}

function Employee() { }

function Bridge() {}
Bridge.prototype = Person.prototype;
Employee.prototype = new Bridge();
Employee.prototype.constructor = Employee;

const e = new Employee();
e.prototypeHi(); // hi
e.staticBye(); 	 // TypeError: e.staticBye is not a function

<2>

function Person() {
	this.staticBye = function() {
		console.log("bye");
	}
}
Person.prototype.prototypeHi = function() {
	console.log("hi");
}

function Employee() { }

Employee.prototype.__proto__ = Person.prototype;

const e = new Employee();
e.prototypeHi(); // hi
e.staticBye(); 	 // TypeError: e.staticBye is not a function

<1>: bridge를 사용한 경우

<2>: __proto__ 로 연결한 경우

이 경우 __proto__ 를 사용하였을 때와 같은 결과를 보여주는 것 같은데, bridge를 사용하는 이유가 어떤 이유일지 궁금해서 질문을 드리게 되었습니다.

추가로 new 키워드로 prototype과 연결했을 때 (Employee.prototype = new Bridge();) Employee의 prototype과 constructor에 어떤 일이 일어나는지 알아보고 싶은데, 어떻게 검색해야 할지 감이 잘 오지 않아서 혹시 이 부분에 대해서 관련한 키워드 조금만 던져주시면 정말 감사하겠습니다!!

좋은 강의 정말 잘 듣고 있습니다!!

답변 5

·

답변을 작성해보세요.

2

코드로 설명 드릴게요.

function Person() {}
Person.prototype.hello = function() {}
function Employee() {}

function Bridge() {}
Bridge.prototype = Person.prototype;
Employee.prototype = new Bridge();

const employee1 = new Employee();
const employee2 = new employee1.constructor();

console.dir(employee1);
console.dir(employee2);

마지막에 `Employee.prototype.constructor = Employee;` 를 뺐습니다.
그러면 employee1만 만들때까지는 큰 문제가 없어보이지만,
실은 constructor를 제대로 가리키지 못하는 문제가 생긴 겁니다.
확인차 employee2는 employee1의 constructor로 생성해보았는데,
employee2는 Employee가 아닌 Person의 인스턴스가 되고 맙니다.
Employee.prototype 내부에 constructor 프로퍼티가 없으니
프로토타입체이닝을 타고 상위(Person.prototype)의 constructor를 찾아갔기 때문이죠.

2

좋은 질문입니다!

이 강의는 ES5까지만을 전제로 진행하였습니다.
ES5까지는 __proto__ 라는 프로퍼티는 표준이 아니었습니다.
[[prototype]] 이라는 '명세'에 따라 브라우저들이 각자 편의에 맞게 구현해놓은 것이죠.

이 당시에는 어떤 브라우저에서 실행하느냐에 따라서
`A.__proto__ = X`
로 프로토타입 체이닝이 되는 경우도 있고, 그렇지 않은 경우도 있었습니다.
성공하는 경우라 하더라도 '비표준'이기 때문에 권장하지 않는 방법이었죠.

그런데 ES6에 와서는 __proto__ 가 표준이 되었습니다.
이제는 모던 브라우저들에서 전혀 문제 없이 동작하고 있습니다.
다만 TC39가 ES6에서 이를 표준으로 지정한 이유는,
당시에 이미 그렇게 동작하는 브라우저들이 있었고,
이를 바탕으로 작업한 "비표준" 자바스크립트 코드들이 세계 여기저기에 널려있었기 때문에
호환성 차원에서 표준으로 인정하는 것이 불가피하다고 판단했기 때문으로 알고 있습니다.

그러니까 현재로서는 __proto__와 Bridge를 활용한 방안의 차이는 없고,
강의 내용은 어디까지나 ES5에서 제공하는 기법만을 가지고 연결하는 기법을 소개한 것이지만,
여전히 __proto__에 값을 직접 대입하는 방식은 추천하지 않습니다.

자세한 내용은 아래 링크를 참고하세요.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

0

전환오님의 프로필

전환오

2021.01.24

저도 의문이었는데  답이되었습니다

0

niobbam님의 프로필

niobbam

질문자

2020.08.01

헉 이것도 이렇게 빨리 달아주실줄이야... 엄청 자세한 설명도 너무나 감사합니다!!

0

niobbam님의 프로필

niobbam

질문자

2020.07.31

오오 빠른 답변에 자세한 설명까지... 무려 링크도...  너무 감사드립니다!!!

저 추가적으로 new 키워드로 prototype과 연결했을 때 (Employee.prototype = new Bridge();) Employee의 prototype과 constructor에 어떤 일이 일어나는지 알아보고 싶은데 어떻게 검색해야 할지 감이 잘 오지 않아서... 혹시 이 부분에 대해서 관련한 키워드 조금만 던져주시면 정말 감사하겠습니다!!