2010-11-24 8 views
3
function Entity() { 
    this.a = {a: 4}; 
    this.b = 5; 
} 

function Thing() {} 
Thing.prototype = new Entity; 

var thing1 = new Thing; 
thing1.a.a = 3; 
thing1.b = 4; 
var thing2 = new Thing; 
console.log(thing2.a.a); // prints 3 instead of 4. I would like 4. 
console.log(thing2.b) // prints 5 as wanted 

자바 스크립트에서 프로토 타입 상속을 설정하는 데 어려움이 있습니다. 이상적으로 나는 thing1과 thing2가 모두 "새로운 엔티티 프로토 타입"의 깨끗한 복사본을 가지길 원합니다.어떻게 체인 된 자바 스크립트 프로토 타입 상속을 사용합니까?

사용 this.__proto__ 내가 피하고 싶은 무언가이다

[편집]

내가 어떻게 작업의 대략적인 생각을 가지고있다.

설정 thing1.b는 Thing 인스턴스의 b 속성을 설정합니다. 프로토 타입 체인에 정의 된 Entity.b를 만지지 않습니다.

여기서 "설정되지 않은 상태로 설정할 수 없습니다"라는 오류가 발생하여 인스턴스 인스턴스의 thing1.a.a를 설정할 수 없습니다. 이것은 정의 된 Entity.a를 찾기 위해 프로토 타입 체인을 올라가 Entity.a.a를 새로운 값으로 설정할 때입니다.

[또한 편집] @IvoWetzel으로

속성을 설정하면하지 않기 때문에 프로토 타입 체인에 닿지 않도록 thing1.b을 설정했다. 어디로 설정 thing1.a.a 두 단계를 수행합니다. .A

+0

덜 혼동스러운 변수 이름을 사용할 수 있습니까? 아마도 멤버 변수와 전역 변수 모두에 대해 a와 b를 재사용하지 마십시오. foo, bar, baz 또는 다른 것을 시도해보십시오. –

+0

나는 약간 더 현명한 것을 사용했다. 아마 현명하다. – Raynos

답변

6

당신이 할 수있는 일의 세터 다음에 프로토 타입 체인에 닿을 thing1.a에 게터에 예를 들어, Thing 내부에 Entity 생성자의에게 논리를 적용한다 :

function Entity() { 
    this.a = {a: 4}; 
    this.b = 5; 
} 
Entity.prototype.c = 6; 

function Thing() { 
    Entity.apply(this, arguments); // ejecutes the assignments made in Entity 
} 
Thing.prototype = new Entity; 

var a = new Thing; 
a.a.a = 3; 

var b = new Thing; 
console.log(a.a.a); // 3 
console.log(b.a.a); // 4 

console.log(a.b); // 5 
console.log(b.b); // 5 

console.log(a.c); // 6 
console.log(b.c); // 6 
+0

그게 문제를 해결하지만 a.a.a가 a.a & a.로 새 Entity 객체 내부에서 무언가를 참조하는 이유를 설명하지 않습니다.b 새로운 Thing 객체 내에서 무언가를 참조하십시오. – Raynos

+0

OP가 프로토 타입을 클래스처럼 작동하도록 요청하는 경우 OP가 수퍼 클래스 생성자를 호출해야 함이 의미가 있습니다. –

+0

정말로, 그렇습니다. '.a.a'를 사용하면 객체 내부의 값을 설정하므로 객체는 공유되지만'.b' 값은 다시 할당됩니다. 거의 모든 언어에서 공통적으로 사용되는 표준 참조 및 값어치 자료입니다. 그런 식으로 슈퍼를 부르는 것이 올바른 방법입니다. –

0

JavaScript 개체는 항상 참조로 처리되기 때문입니다.

따라서 a.a.a = 3;을 수행하여 this.a 개체를 변경하면 해당 개체가 메모리에서 변경됩니다. Thing의 새 인스턴스는 Thing이 될 때마다 Entity 생성자가 호출되지 않고 this.a 개체가 동일하게 유지되므로 메모리의 동일한 개체를 참조합니다.

아마도 Thing 생성자 내부에 this.a을 프로토 타입 체인 외부에 넣겠습니다. 그러면 Thing이 인스턴스화 될 때마다 this.a의 새 버전이 메모리에 생성됩니다.

+0

this.a는 Entity 생성자에 있습니다. – Raynos

2

CMS가 해결책을 게시하는 동안 thing2.b이 5를 반환하는 이유는 무엇이며 thing2.a.a이 해당 객체로 해결되는 이유는 무엇입니까?

var thing1 = new Thing; 

// thing1 has no a, but the prototype has so a.a is essentially the a of Entity 
thing1.a.a = 3; 

// Sets b on thing1, setting does not go up the prototype chain(!) 
thing1.b = 4; 

// that's what thing1 looks like 
Thing {proto: Entity { 
         a: { <--- gets resolved 
          a: 3 <-- gets set 
         }, 
         b: 5 
       }, 
       b: 4 <-- gets set directly 
     } 


var thing2 = new Thing; 

// thing2.a does not exist, so we look up the prototype and find a on Entity 
console.log(thing2.a.a); 

// thing2.b also does not exists, so once again we look up the prototype to find b on Entity 
console.log(thing2.b); 

// that's what thing2 looks like 
Thing {proto: Entity { 
         a: { 
          a: 3 <- gets resolved 
         }, 
         b: 5 <- gets resolved 
       } 
     } 

모든 문제는 속성을 찾기 위해 자바 스크립트가 프로토 타입 체인으로 올라가는 것에 관한 것입니다. 하지만 재산을 설정할 때 으로 올라가지 않습니다.

+0

a.a.a가 a.a를 Thing에 설정하지 않는 이유는 무엇입니까? 그게 뭔지 정말 궁금해. – Raynos

+0

내 대답을 업데이트하고 지금은 분명해야합니다. –

관련 문제