pDestiny
(P Destiny)
11월 27, 2017, 7:07오전
1
지금 prototype공부하고 있는데 기본적인 개념 자체는 그렇게 어렵지 않지만
깊이 들어가려니 상당히 복잡한 것 같습니다.
특히 이상한 현상을 발견했는데,
객체가 다른 prototype으로부터 상속을 받았을 경우
상속 받기 전 constructor에 접근 하는 것이 불가능한 깨짐 현상이 나타납니다.
아래 코드가 그 예인데
function Foo(){} //Foo constructor 생성
function Bar(){} //Bar constructor 생성
Bar.prototype = Foo.prototype; //직접 상속받기
var bar_instance = new Bar();
console.log(bar_instance.constructor); //bar 인줄 알았는데, foo가 나옵니다.
console.log(bar_instance instanceOf Bar); //true 입니다.
이제 Bar 생성자를 직접 사용하는 방법 외에 Bar에 접근하는 방법은
더이상 존재하지 않는 것으로 보입니다.
bar_instance의 참조 프로토타입도, 생성자도 Foo.prototype과 Foo가 되어
마치 Bar는 사라진 것으로 보입니다.
현재 위의 그림이 제가 작성한 코드의 구조입니다. 위에서 중요한 점은 위에서 말했듯이
Bar 생성자에 접근을 할 수 없다는 점입니다.
Bar로 생성된 객체들은 constructor와 __proto__를 사용할 경우에도, 또 Bar.prototype을 이용하더라도
Foo로만 접근하게 됩니다.
이렇게 사라진 것으로 보이는 Bar가, instanceof 연산자를 통할경우 bar_instance가 Bar의 인자라는 것을 어떻게 확인한 것인지 궁금하네요!
이 구조에서 Bar 에 접근할 수 있는(Bar를 직접 수정하는 것 이외에) 방법이 있는지도 궁금합니다.
.
그리고 이 부분은 상속은 아니고 레퍼런스를 대치해버린거죠…
1개의 좋아요
윗분처럼 해야 하는 이유는, 질문처럼
Bar.prototype = Foo.prototype;
이렇게 했을 시, 레퍼런스 대입이 되기 때문에,
Bar.prototype에 변경이 일어날 경우 Foo.prototype 에도 영향이 미치게 됩니다.
그렇게 되면 부모 클래스라는 의미가 퇴색되는거죠.
그렇기 때문에 기존 프로토타입에서 입 싹 닫고 새로이 대입하여 수박이라 치면, 수박 식물 째로 영향받지 않고, 수박 열매만 적용하도록 생각하시면 됩니다.
그리고 마지막으로 레퍼런스 특성 상 결국 Foo 소속이기 때문에
Bar.prototype.constructor = Bar;
이런 식으로 생성자를 덮어버려서 완벽한 Bar의 Foo 상속 효과를 얻게 되는거죠.
네. 상속은 맞긴 맞아요. 단지 상속 효과를 내기 위한 방법론일 뿐이죠.
2개의 좋아요
ho1234c
(정종호)
11월 27, 2017, 8:04오전
6
prototype객체와 constructor객체는 서로 참조하고 있습니다. Bar의 prototype을 Foo의 prototype으로 overwrite했기때문에
Bar.prototype.constructor와 Foo.prototype.constructor가 모두 Foo입니다. 따라서
bar_instance.constructor
는 Foo가 나옵니다.
그리고 instanceof 라는 키워드는 bar_instance라는 객체의 프로토타입 체인 내에 constructor로 Bar의 constructor가 있는지를 확인할텐데, Bar.prototype.constructor가 Foo이기 때문에 true입니다.
추가 : A instanceof B 는 A의 프로토타입체인 내에 B.prototype이 있는지를 확인하는 식으로 동작하기때문에
Bar.prototype == Foo.prototype == bar_instance.__proto__
여서 true입니다. 만약
bar_instance.__proto__ = Foo.prototype
처럼 했다면
bar_instance instanceof Bar
는 false일겁니다.
3개의 좋아요
pDestiny
(P Destiny)
11월 27, 2017, 12:40오후
7
그 부분에 대해서도 글을 쓸 예정입니다. 저문제가지고 고민하다보니
프로토타입이 좀 이해가 가는 것 같습니다
pDestiny
(P Destiny)
11월 27, 2017, 12:54오후
9
@ho1234c
가장 확실한 답변이라고 생각해요!! 답변 감사합니다
그런데 예제를 실행해 보니 false가 아니라 true로 나오네요
ho1234c
(정종호)
11월 28, 2017, 4:07오전
10
@pDestiny scope내에서 뭔가 다른 코드를 실행하셨을것같아요. 제 예시는 아래와 같은 상황입니다
function Bar(){};
function Foo(){};
var bar_instance = new Bar();
bar_instance.__proto__ = Foo.prototype
bar_instance instanceof Bar // false 입니다.
1개의 좋아요
pDestiny
(P Destiny)
11월 28, 2017, 5:11오전
11
@ho1234c 아하! 이제 알았습니다!!!
Bar.prototpye과 Bar로 만들어낸 인스턴스가 가르키는 프로토타입이 다를 수 있는거군요!!
instanceof가 어떻게 작동하는지 이해 할 수 있을 것 같습니다.
예제는 확실히 false네요 ㅎ
답변 감사합니다.