2012-07-28 9 views
3

다음 코드에 따라 프로토 타입 체인이 설정되는 방법을 파악하는 데 문제가 있습니다.Object.create를 통해 생성 된 객체의 프로토 타입 설정

object.prototype = object.fn = Object.create(this.prototype); 

내가 다시 모델로 프로토 타입 포인트의 새로운 객체를 만드는 방법을 만드는 방법을 이해하지만, 끝에서 두 번째 줄은 것을 덮어 쓸 것 같다

var Model = { 
    prototype: { 
     init: function(){}, 
     log: function(){ console.log('instance method log was called') } 
    }, 
    log: function(){ console.log('class method log was called') }, 
    create: function() { 
     var object = Object.create(this); 
     object.parent = this; 
     object.prototype = object.fn = Object.create(this.prototype); 
     return object; 
    }, 
    init: function() { 
     var instance = Object.create(this.prototype); 
     instance.parent = this; 
     instance.init.apply(instance, arguments); 
     return instance; 
    } 
} 

var User = Model.create(); 
User.log(); // 'class method log was called' 

// create a new method after creation 
Model.warn = function() { console.warn('warn was called') } 

User.warn() // 'warn was called' 

var user = User.init(); 
user.log(); // 'instance method log was called' 

는 특히이 라인은 만드는 방법에 나를 혼란 새로운 객체 (Model.prototype)를 가진 프로토 타입. 그러나 새 객체를 만든 후에도 모델에 메서드를 추가 할 수 있으므로 원래 프로토 타입은 그대로 유지되며 새 객체는 여전히 액세스 할 수 있습니다.

누군가 실제로 일어나는 일에 대해 밝힐 수 있습니까?

편집 -이 코드를 지적해야 오라일리

에 의해 자바 스크립트 웹 응용 프로그램에서 오는
+1

당신을 혼란스럽게하는 것에 대해서는 약간 불명확하지만, 아마도'this'와'object'는'Model.create'에서 같은 것을 가리키고 있다고 생각할 것입니다. 그렇다면 그렇지 않습니다. 'this'는'Model'에 대한 참조이지만'object'는'Object.create (this)'에서 생성 된 새로운 객체에 대한 참조입니다. 그래서'object.prototype = ... whatever'을 할 때, 당신은'Model.prototype'을 덮어 쓰지 않고,'object'의 프로토 타입 체인에 존재하는'.prototype' 프라퍼티를 'object'에 똑같은 이름을 가진 속성. –

+0

나는이 '모델'과 '객체'가 새로운 객체라는 것을 이해한다. 오히려 나 혼란 스럽다. 처음에는 Object.create가 새로운 객체 프로토 타입을 '모델'로 설정하지만 나중에 몇 줄의 객체가된다. 프로토 타입은 Object.create (this.prototype)로 재설정됩니다. 그것이 내가 이해하지 못하는 선이다. 나에게 그것은 object.prototype이 이제 프로토 타입이 Model.prototype (init 및 log 함수)로 설정된 객체로 설정되었지만 반환 된 객체는 Model에서 직접 메소드에 액세스 할 수 있습니다. – jhummel

+2

당신을 혼란스럽게하는 것 같아요. 'object'에 설정된'.prototype' 속성은 프로토 타입 체인 자체와는 아무런 관련이 없습니다. 일단 객체를 만들면 프로토 타입 체인을 변경할 수 없습니다. 그래서 값이'object.prototype'에 쓰여질 때,'object'와'Model' 사이의 관계에 전혀 간섭하지 않습니다. '.prototype' 속성을 설정하는 유일한 시간은 프로토 타입 체인에 영향을 미치며,'.prototype' 속성을 생성 한 다음 생성자로 만든 미래 객체 만 해당 변경의 영향을받습니다. –

답변

2

좋아. 그래서 그냥 삭제 잡음 코드,이 코드에 대해 묻는 :

var Model = { 
    prototype: {}, 
    create: function() { 
     var object = Object.create(this); 
     object.prototype = Object.create(this.prototype); 
     return object; 
    } 
}; 

Model.create() 함수가 (프로토 타입) 모델을 확장하는 새 개체를 만들고, 용이의 첫 번째 줄을.

하지만 다음 줄이 객체 "프로토 타입"속성을 덮어 쓰므로 회신을 받았습니다. 그것은 객체의 프로토 타입이 아니며 객체 프로토 타입은 여전히 ​​모델이며 [[Prototype]]이라는 숨겨진 속성에 저장됩니다. 코드가 수정하는 속성은 객체의 [[Prototype]]과 아무 상관이 없습니다. 이름. 현실을 이해하기 위해 이름을 변경하자이 동일합니다 :

var Model = { 
    blablabla: {}, 
    create: function() { 
     var object = Object.create(this); 
     object.blablabla = Object.create(this.blablabla); 
     return object; 
    } 
}; 

그것은 당신이 변경 될 때 Model.blablabla 그렇게 object.blablabla이 Model.blablabla에 영향을주지 않습니다 확장합니다.

var SubModel = Model.create(); 
SubModel.blablabla.newMethod = function() { }; 
console.log(Model.blablabla.newMethod); // undefined 

여러 번 필드의 올바른 이름을 선택하면 모양보다 중요합니다.