2011-07-30 7 views
10

누군가이 코드를 사용하고 있다고 생각하면 Me.prototype.constructor = Me;을 사용하는 이유를 설명 할 수 있습니까?JS에서 프로토 타입 생성자를 사용

코드 프로토 타입 개체가 Me 개체에 만들어지고 인스턴스화되어 이전 프로토 타입 개체로 대체됩니다. 주어진 코드에서 Me 생성자를 가리켜 야하는 이유는 무엇입니까?

function Me(){ 
    this.name = 'Dejan'; 

} 

function You(){ 
    this.name = 'Ivan'; 
} 

Me.prototype = new You(); 

somebody = new Me(); 

Me.prototype.constructor = Me; // Why? 

Me.prototype.foo = function(){ 
    alert('Proto Me!'); // It always fire up this alert, ether constructor is pointing to Me or not... ! 
} 

You.prototype.foo = function(){ 
    alert('Proto You!'); 
} 

somebody.foo(); 
alert(somebody.name); // Alert 'Dejan' 
+0

레거시 브라우저는'instanceof' 키워드의'.constructor' 속성을 확인합니다. – Raynos

+0

2006 년부터 책입니다. –

답변

11

이 필요하지 않을 것, 그리고 심지어 통념 instanceof 반대에 필요하지 않은 것 (instanceof를 내부적으로 프로토 타입 체인을 확인하고 생성자 속성을 필요로하지 않는다). 일반적으로 constructor은 생성자의 prototype에서 열거 할 수없는 속성입니다. 따라서 해당 생성자에 의해 인스턴스화 된 모든 객체를 제공하면 해당 생성자를 가리키는 열거 할 수없는 constructor 속성이 생성됩니다.

이상적으로는 열거 할 필요가 없으면 넣으면 좋습니다. 일부 코드에서는 객체에 .constructor이 있다고 가정합니다.

당신이 자식 프로토 타입 역할을하도록 인스턴스화 한 객체가 잘못된 것을 가리키는 생성자 속성을 가지고 있으므로 생성 된 코드에서 생성자를 재설정해야합니다 (거기에 원하는 경우). 생성자 (생성자).

ES5에서, 당신이 할 것 :

Child.prototype = Object.create(Parent.prototype, { 
    constructor: { value: Child, enumerable: false } 
}); 

편집 : 비표준 __proto__을 사용하여 상속을 할 때 또한, 언급 할 가치가있을 수도 있습니다, 그것은 __proto__ 단지 지정 및 객체의 프로토 타입 때문에 생성자를 재설정 할 필요는 없습니다 , 말하자면, 자신의 속성이 존재하지 않을 때 조회가 수행 될 객체. 새로운 prototype에는 항상 constructor이라는 속성이 있습니다. 일에

그래서는 : child.prototype의 기본 생성자 속성이 여전히 존재하기 때문에

var child = function() {}; 
child.prototype.__proto__ = parent.prototype; 

당신은 생성자를 설정할 필요가 없습니다. 액세스 된 경우 프로토 타입 체인 조회를 수행 할 필요가 없습니다. 당신은 당신이 그것을 설정하기 전에를 찾을 수

console.log(Me.prototype.constructor); 
Me.prototype.constructor = Me; // Why? 

으로 라인

Me.prototype.constructor = Me; // Why? 

를 교체하는 경우 Me.prototypeYou의 인스턴스이기 때문에

+2

IE6에서'constructor' 속성을 확인하지 않습니까? 그리고'Object.create'는 당신을위한'constructor' 속성을 설정합니다. 당신은 수동으로하지 않아도됩니다. – Raynos

+4

Raynos, 아니요, IE6에 대해서는 잘 모르겠지만, IE6에 대해서는별로 신경 쓰지 않습니다. 또한 Object.create는 생성자를 설정하지 않습니다. 생성자 개념이 없습니다. 실제로는 Object.create의 포인트입니다. 부모 생성자와 동일한 생성자 속성 만 가져오고 상속에 잘못 될 수 있습니다. 그래서 당신은 그것을 바꿀 필요가 있습니다. – chjj

+1

당신의 권리는'건설자'에 관한 것입니다. Object.create에는 생성자의 개념이 없습니다. – Raynos

5

, Me.prototype.constructor 인해 라인, You입니다

Me.prototype = new You(); 

그래서, th e // Why?이 방법으로 상속을 수행하여 JavaScript를 부여한이 잘못된 인상을 "고치려면"주석이 필요합니다.


본질적 문제는 고전적인 상속을 구현하기 위해 프로토 타입 상속을 사용하려고하기 때문에 대해 제공됩니다. 프로토 타입 상속은 객체 인스턴스에서 작동하며 "클래스"또는 실제로는 "유형"개념이 없지만 자바 스크립트는 전체 new, .constructorinstanceof 비즈니스와 혼동을줍니다."여기

function begetPart(partNumber, description) { 
    return Object.create({}, { 
     number: { value: partNumber }, 
     description: { value: description }, 
     describe: { 
      value: function() { 
       alert(this.description); 
      } 
     } 
    }); 
} 

function begetTire(partNumber, speed) { 
    return Object.create(
     begetPart(partNumber, "A tire"), 
     { 
      speed: { value: speed }, 
      describe: { 
       value: function() { 
        alert(this.description + "; speed = " + this.speed); 
       } 
      } 
     } 
    ); 
} 

var genericPart = begetPart(1234, "A widget"); 
genericPart.describe(); // alerts "A widget" 

var tire = begetTire(4567, "fast"); 
tire.describe(); // alerts "A tire; speed = fast" 

우리가 말을 Object.create를 사용

이런 종류의 일을 더 프로토 타입 방법은 당신이 원하는 양식 객체를 반환 전원 생성자, 즉 기능에 찬성 생성자를 피하다하는 것입니다 이 다른 객체 인스턴스를 기반으로 객체 인스턴스를 만듭니다. " 다른 인스턴스는 begetPart에 대한 새 빈 개체이고 일부 속성은 begetTire으로 미리 채워진 새로운 "부분 인스턴스"입니다.

프로토 타입 상속에서 객체 인스턴스가이 "유형"또는 "클래스"아이디어를 얻지 않고 다른 객체 인스턴스를 상속하므로 실제로 JavaScript와 프로토 타입 상속이 실제로 어떻게 작동 하는지를 잘 반영합니다.

+0

'function Object() {[native code]}' – towry