2012-02-13 4 views
33

나는 그런 예가있다.프로토 타입에서 생성자 함수를 변경하는 것이 왜 불가능합니까?

function Rabbit() { 
    var jumps = "yes"; 
}; 
var rabbit = new Rabbit(); 
alert(rabbit.jumps);     // undefined 
alert(Rabbit.prototype.constructor); // outputs exactly the code of the function Rabbit(); 

은 내가 var jumps 공개 될 정도로 Rabbit()의 코드를 변경하고 싶습니다. 나는 이렇게한다 :

Rabbit.prototype.constructor = function Rabbit() { 
    this.jumps = "no"; 
}; 
alert(Rabbit.prototype.constructor); // again outputs the code of function Rabbit() and with new this.jumps = "no"; 
var rabbit2 = new Rabbit();    // create new object with new constructor 
alert(rabbit2.jumps);     // but still outputs undefined 

왜 이런 식으로 생성자 기능의 코드를 변경할 수 없습니까?

+0

당신의 두 번째 코드는 거짓, 따라서 오류로 평가하는 래빗 점프하지 않습니다 말한다 -'this.jumps = "예"' – wheresrhys

+0

@wheresrhys을하려고 모든 비어 있지 않은 문자열 (큰 길이 즉, 문자열 0보다) JavaScript에서 true로 평가됩니다. – Max

답변

56

는 '클래스'의 사용자가 인스턴스 생성자를 검색 할 수 있도록 Rabbit.prototype.constructor는, 원래의 생성자 (function Rabit(){...}) 단지 포인터입니다 것입니다 :

여기 내 jsfiddle입니다. 따라서 시도 할 때

Rabbit.prototype.constructor = function Rabbit() { 
    this.jumps = "no"; 
}; 

원래 생성자와 프로토 타입에 대한 참조가 연결되어 있습니다.

function extend(base, sub) { 

    function surrogateCtor() {} 
    // Copy the prototype from the base to setup inheritance 
    surrogateCtor.prototype = base.prototype; 
    // Tricky huh? 
    sub.prototype = new surrogateCtor(); 
    // The constructor property is set wrong (to the base constructor) 
    // with the above trick, let's fix it 
    sub.prototype.constructor = sub; 
} 

당신은 것을 볼 수 있습니다 그래서 대답은, 아니, 당신은

많은 도서관은 다음과 같은 뭔가 상속을 구현 JS에 prototype.constructor

상속에 재 할당하여 생성자를 변경할 수있다 위의 코드에서 생성자 속성을 수정해야하지만 실제 생성자에는 영향을 미치지 않습니다. JS 상속에 대한 내 게시물을 참조 http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

생성자를 재정의하는 방법 당신이 정말로 생성자를 재정의하고 싶은 경우에, 다만 할

var oldProto = Rabbit.prototype; 
Rabbit = function() {...}; 
Rabbit.prototype = oldProto; 
+2

예,'prototype.constructor'는 아무 것도 영향을 미치지 않습니다. – katspaugh

+1

+1 좋은 답변입니다. – Jivings

0

는 다음

function Rabbit() { 
    this.jumps = "no"; 
}; 

var rabbit = new Rabbit(); 
alert(rabbit.jumps); // Prints "no" 
+2

프로토 타입에서 '점프'설정이 작동하지 않는 이유를 설명하면이 대답을 '+ 1'로 지정합니다. –

+0

예, 고맙습니다. 원래 기능을 변경할 수 있음을 알고 있습니다. 하지만 프로토 타입에서 다른 방법으로 변경하는 것이 가능한지 알고 싶습니다. – Green

1

이 시도하십시오 :

Rabbit.prototype = new function(){ 
    this.jumps = "no"; 
}; 

var rabbit2 = new Rabbit();    // create new object with new constructor 
alert(rabbit2.jumps); 

을 대신 생성자를 설정하는 개체가 생성 될 때 따라서, 새로운 기능으로 프로토 타입 객체을 설정하려면 프로토 타입을 실행하고 this.jumps을 no로 설정하여 이전 생성자가 설정 한 값을 무시합니다. 무슨 일이 일어나고 무엇 http://jsfiddle.net/ZtNSV/9/

+1

이것은 실제로 작동하지 않습니다. 프로토 타입 자체에 점프를 설정하는 것과 같습니다. ''Rabbit.prototype = {jumps : 'no'};''를 호출하면 이미 그렇게 할 수 있습니다. 그러나 그 프로토 타입은 생성자 함수의 어떤 것에 의해 무시 될 것이므로 실제로 그렇게하고 싶지는 않을 것입니다. – danShumway

0

, 문자 그대로의하지에서 객체를 생성 이것은 좋은 해결 방법 생성자 함수에서.

먼저 생성자의 로컬 변수가 아닌 jumps 멤버를 객체에 포함하려면 this 키워드가 필요합니다.

function Rabbit() { 
    this.jumps = "yes"; 
}; 

var rabbit = new Rabbit(); 
alert(rabbit.jumps);     // not undefined anymore 

그리고 지금 당신은 쉽게 지금 당신이 원하는 공개적 방법 jumps에 액세스 할 수 있습니다

rabbit.jumps = 'no'; 
alert(rabbit.jumps);     // outputs 'no' 

하지만 여전히 다른 토끼 개체를 만드는 경우 처음에 '예'생성자에 정의 된 것을 마우스 오른쪽 ?

var rabbit2 = new Rabbit(); 
alert(rabbit.jumps);      // outputs 'no' from before 
alert(rabbit2.jumps);     // outputs 'yes' 

기본 토끼 개체에서 토끼를 만드는 것이 가능합니다. 구체적인 토끼 개체 (구현)의 값을 변경하지 않으면 콘크리트 토끼는 항상 기본 토끼 개체에서 기본값을 변경할 수 있습니다. 이것은 아마 가장 좋은 @ Juan Mendes의 해결책과는 다르지만 또 다른 관점을 열 수 있습니다.

Rabbit = {jumps : 'yes'}; // default object 

rabbit = Object.create(Rabbit); 
Rabbit.jumps = 'no'; 
rabbit2 = Object.create(Rabbit); 

console.log(rabbit.jumps); // outputs "no" - from default object 
console.log(rabbit2.jumps); // outputs "no" - from default object 

// but... 
rabbit.jumps = 'yes'; 
Rabbit.jumps = 'unknown'; 

console.log(rabbit.jumps); // outputs "yes" - from concrete object 
console.log(rabbit2.jumps); // outputs "unknown" - from default object 
관련 문제