2014-11-16 6 views
1

내가 자바 스크립트에 새로운 오전과 함께Javascript 프로토 타입 상속을 사용하여보아야 할 동작입니까?

이 문서를 상속을 사용하는 방법에 대한 질문이 지금까지 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#More_flexible_constructors)를 도움이되었습니다,하지만 크롬의 디버거에서 관찰하고있는 행동은 제가 좋겠 일치하지 않는 것 기대해. 나는이 볼 디버거에서

Base = function() { 
    this.value = 0; 
}; 

Base.prototype.constructor = Base; 

Derived = function() { 
    Base.call(this); 
}; 

Derived.prototype = new Base(); 
Derived.prototype.constructor = Derived; 

:

내가 이가지 경우가 할당을 통해 스테핑 후

enter image description here

enter image description here

을,이

참조 enter image description here

인스턴스의 값이 변경되었지만 프로토 타입의 값이 변경되지 않았습니다. 예상 되나요?

내가 확실히 이해하지 못하는 두 번째 방법은이 (여기 참조 다시 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#More_flexible_constructors (섹션 '재산 상속 재 방문')

Base = function() { 
}; 

Base.prototype.constructor = Base; 
Base.prototype.value = 0; 

// Derived as before... 

enter image description here

이후의 하단에 냈다 코드를 참조

enter image description here

값이 새로 추가 된 과제 속성. 이 프로토 타입의 값을 변경하면 안됩니까? 또는 프로토 타입을 통과하여 명시 적으로 값에 액세스해야합니다 (예 : derived.value.prototype.value = 5

이 정보는 크게 감사하겠습니다!

감사합니다.

UPDATE :

는 응답 모든 사람에게 감사는, 그것이 적절한 시간에 Object.create를 사용하지 않는 내 함께 할 수 있었다 밝혀졌습니다.

enter image description here

및 디버거에서 내가 기대했던 가지고 : 나는이 내 코드를 업데이트

enter image description here

이 바로 보인다! :)

enter image description here

는 당신의 도움을 @sixfingeredman 주셔서 감사하고 @Bergi!그것은 유용한 아무것도하지 않는

Base.prototype.constructor = Base; 

:없는 주제에있는 동안

+0

예, 예상됩니다. – Bergi

+0

Child의 프로토 타입을 설정하기 위해 Parent 인스턴스를 생성하지 마십시오. 대신 Object.create 상속 및 혼합 기능을 사용하는 방법은 여기에서 자세히 설명합니다. http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR

답변

2

먼저,이 줄을 제거합니다.

이제 네 질문에, 예, 동작이 예상됩니다. .prototype을 업데이트했다고 상상해보십시오. .prototype이 모든 인스턴스간에 공유되므로 모든 인스턴스에 업데이트가 표시됩니다. 확실히 당신이 원하는 것이 아니 겠지요. 당신이 이런 짓을하면

는 :

var derived = new Derived(); 

당신은 Derived.prototype에서 상속하는 새로운 객체를 만들었습니다. 이했을 때

는 그리고 :

derived.value = 1; 

을 당신은 새로운 객체에 직접 값을 할당합니다.

그래서 할당하기 전에, 상속의 체인이처럼 보였다 :
derived   Derived.prototype  Base.prototype  Object.prototype 
+-----------+   +-----------+   +-----------+   +-----------+ 
|   |   |   |   |   |   |   | 
|   |---------| value:0 |---------|   |---------|   | 
|   |   |   |   |   |   |   | 
+-----------+   +-----------+   +-----------+   +-----------+ 

그리고 할당 한 후, 그것은 다음과 같습니다

:

derived   Derived.prototype  Base.prototype  Object.prototype 
+-----------+   +-----------+   +-----------+   +-----------+ 
|   |   |   |   |   |   |   | 
| value:1 |---------| value:0 |---------|   |---------|   | 
|   |   |   |   |   |   |   | 
+-----------+   +-----------+   +-----------+   +-----------+ 

그래서 할당하기 전에, 당신은 고개 경우 derived 개체에 value 개체가 있으면 찾을 수 없으므로 Derived.prototype으로 넘어 가서 찾을 수 있습니다.

그러나 과제가 완료되면 derived 개체에 value이 바로 표시됩니다.


그리고 두 번째 방식에

은 프로토 타입 체인 대신 다음과 같이 찾고 시작할 것입니다 :

derived   Derived.prototype  Base.prototype  Object.prototype 
+-----------+   +-----------+   +-----------+   +-----------+ 
|   |   |   |   |   |   |   | 
|   |---------|   |---------| value:0 |---------|   | 
|   |   |   |   |   |   |   | 
+-----------+   +-----------+   +-----------+   +-----------+ 

을 그래서 derivedvalue을 찾을 때, 그것은 전에 Base.prototypeDerived.prototypederived에서 통과 것 value 속성을 찾습니다.


그럼 Derived 생성자에서 여러 개체를 만들었습니다. 위의 스케치가 변경되어 사용자가 만든 각 객체가 Derived.prototype을 가리킬 수 있습니다.

derived_1 
+-----------+   
|   | 
|   | 
|   | 
+-----------+ 
      \______ 
        \ 
        \ 
    derived_2   Derived.prototype  Base.prototype  Object.prototype 
+-----------+   +-----------+   +-----------+   +-----------+ 
|   |   |   |   |   |   |   | 
|   |---------|   |---------| value:0 |---------|   | 
|   |   |   |   |   |   |   | 
+-----------+   +-----------+   +-----------+   +-----------+ 
        /
       ______/ 
    derived_3 /
+-----------+   
|   | 
|   | 
|   | 
+-----------+   

이제 프로토 타입을 업데이트하지 않는 이유를 알 수 있습니다.

우리가했던 경우 derived_1.value = 42하고 derived_2derived_3에서 value를 찾아 갔을 때 다음 Derived.prototype 개체를 업데이트 한 경우, 당신은 당신이 derived_1에 할당 된 값을 얻을 것입니다.

+0

안녕하세요! 대단히 대단히 감사합니다. 후드에서 실제로 무슨 일이 일어나고 있는지 조금 더 잘 이해할 수 있다고 생각하지만 상속을 올바르게 사용하는 방법을 알지 못합니다. 이 두 가지 경우 모두 기대하는 바를 수행하면서 실제로 원하는 것을하지는 않습니다. 첫 번째 경우에는 새 값 속성을 만드는 대신 프로토 타입의 속성을 어떻게 수정합니까? – Tom

+0

@Tom : 당신은 현재와 같은 방법으로 프로토 타입을 수정할 것입니다 ...'Derived.prototype.foo = "bar";'를 실행하면됩니다. 각 객체가 고유 한'foo' 속성을 가지고 있지 않으면, 모두 똑같은 "bar"값을 보게 될 것입니다. '.prototype'을 업데이트하고자 할 때만 모든 인스턴스간에 데이터를 공유 할 수 있습니다. 가장 일반적인 예는 모든 객체에 메소드를 제공하는 것입니다. –

+0

또한 정확하게 이해한다면, C# 또는 C++에서 클래스에 정적 멤버를 만드는 것과 비슷한 방법으로 변수를 저장하기 위해 프로토 타입을 사용하겠습니까? – Tom

2

값이 새 속성으로 추가되었습니다. 이 프로토 타입의 값을 변경하면 안됩니까?

아니요,이 동작이 필요합니다. 속성은 설정이 아니라 "점점"에서만 상속됩니다. 개체 의 속성에 값을 할당하면 해당 개체의 속성이 변경 (또는 생성)됩니다.

1 : 거기에 accessor property (setter function) on the prototype

입니다 아니면 명시 적으로 프로토 타입을 통해 이동하여 값에 액세스해야합니까 제외하고 - 예를 들어, derived.value.prototype.value = 5

프로토 타입의 값을 변경하려면 프로토 타입에 값을 지정해야합니다 (예). What is the reason to use the 'new' keyword at Derived.prototype = new Base를 참조 -

Derived.prototype.value = 5; 

또는 Btw는

Object.getPrototypeOf(derived).value = 5; 

,합니다 ( Base 생성자에서 당 인스턴스 생성) 속성이 Derived.prototype에 전혀 존재하지해야한다는 통지가 귀하의 경우에는, 그 것 . 대신 Derived.prototype = new Base;을 사용해야합니다.

Derived.prototype = Object.create(Base.prototype); 
+0

매우 유용한 답변을 주셔서 감사합니다. Object.create (..)를 사용하여 테스트 케이스를 반복하여 원하는 동작을 생성하는지 확인합니다. – Tom

+0

Object.create (..) 사용에 대한 팁이 돈에 있었고, 제 질문을 업데이트했고 문제가 해결되었습니다. 감사합니다! – Tom

관련 문제