2013-07-21 6 views
2

제 질문은 부모 객체의 프로토 타입 체인을 유지하는 자식 객체에 관한 것입니다.JavaScript의 객체 상속

John Resig의 고급 Javascript 슬라이드 (http://ejohn.org/apps/learn/#76)에서 그는 하위 개체의 프로토 타입 체인을 유지 관리하기 위해 새 부모 개체를 인스턴스화해야한다고 말합니다.

그러나 몇 가지 빠른 테스트를 통해 부모 객체 프로토 타입과 동일한 자식 객체 프로토 타입을 설정함으로써 프로토 타입 체인이 유지된다는 것을 알았습니다.

모든 설명이 크게 도움이 될 것입니다.

원본 코드

function Person(){} 
Person.prototype.dance = function(){}; 

function Ninja(){} 

// Achieve similar, but non-inheritable, results 
Ninja.prototype = Person.prototype; 
Ninja.prototype = { dance: Person.prototype.dance }; 

assert((new Ninja()) instanceof Person, "Will fail with bad prototype chain."); 

// Only this maintains the prototype chain 
Ninja.prototype = new Person(); 

var ninja = new Ninja(); 
assert(ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype"); 
assert(ninja instanceof Person, "... and the Person prototype"); 
assert(ninja instanceof Object, "... and the Object prototype"); 

존 레식은 그가 처음 Person.prototype-Ninja.prototype 설정에서 제공하는 코드에서 내 수정 된 버전

function Person(){} 
Person.prototype.dance = function(){console.log("Dance")}; 

function Ninja(){} 

// Achieve similar, but non-inheritable, results 
Ninja.prototype = Person.prototype; 

assert((new Ninja()) instanceof Person, "Will fail with bad prototype chain."); 

var ninja = new Ninja(); 
assert(ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype"); 
assert(ninja instanceof Person, "... and the Person prototype"); 
assert(ninja instanceof Object, "... and the Object prototype"); 
ninja.dance(); 
+1

[이] (http://stackoverflow.com/questions/5991152/why-do-we-use-boy-prototype-new-human-to-simulate-inheritance)에서 – aaronman

+1

도움이 될 "현대적인"브라우저 :'Ninja.prototype = Object.create (Person.prototype)'. – elclanrs

답변

8

. 그리고는 즉시 { dance: Person.prototype.dance }로 재설정합니다

// Achieve similar, but non-inheritable, results 
Ninja.prototype = Person.prototype; 
Ninja.prototype = { dance: Person.prototype.dance }; 

결과는 Ninja 생성자에 의해 생성 된 모든 객체가 직접 Person.prototype의 인스턴스가 아닌 어떤 { dance: Person.prototype.dance }에서 상속 것입니다. 따라서 (new Ninja) instanceof Person은 false를 반환합니다. 이 경우 프로토 타입 체인은 다음과 같습니다 효과적으로 Person.prototypeNinja.prototype을 설정 Ninja.prototype에 두 번째 할당을 제거

 null 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
| Object.prototype | 
+------------------+ 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
| Ninja.prototype | 
+------------------+ 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
|  new Ninja | 
+------------------+ 

수정 된 버전. 따라서 프로토 타입 체인은 다음과 같습니다 Ninja.prototype이 동일하기 때문에 Person.prototype 모두 (new Ninja) intanceof Ninja(new Ninja) instanceof Persontrue를 반환합니다

  null 
     ^
      | 
      | [[prototype]] 
      | 
+-------------------+ 
| Object.prototype | 
+-------------------+ 
     ^
      | 
      | [[prototype]] 
      | 
+-------------------+ 
| Ninja.prototype/| 
| Person.prototype | 
+-------------------+ 
     ^
      | 
      | [[prototype]] 
      | 
+-------------------+ 
|  new Ninja  | 
+-------------------+ 

공지있다. 이는 instanceof operator depends on the prototype of a constructor이기 때문입니다.

자바 스크립트에서 상속을 달성 할 수있는 올바른 방법은 Object.create(Person.prototype)Ninja.prototype를 설정하는 것입니다 그러나 (또는 ​​new Person에 구식 방법) 프로토 타입 체인이 될 것이라고 경우 :

 null 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
| Object.prototype | 
+------------------+ 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
| Person.prototype | 
+------------------+ 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
| Ninja.prototype | 
+------------------+ 
     ^
     | 
     | [[prototype]] 
     | 
+------------------+ 
|  new Ninja | 
+------------------+ 

주 : JavaScript 객체는 다른 객체를 상속한다는 점을 항상 기억하십시오. 그들은 생성자 함수를 결코 상속받지 않습니다. 자바 스크립트에서 실제 프로토 타입 상속에 대해 배우고 싶다면 내 블로그 게시물 why prototypal inhritance matters을 읽어보십시오. 당신이 프로토 타입은 당신이 필요 달성하기 위해 자바 스크립트로 작동하는 방식이 마음에 들지 않는다면

+0

멋진 블로그 글. 리소스를 가져 주셔서 감사합니다! –

1

,이 봐 복용 좋을 것 : https://github.com/haroldiedema/joii

그것은 기본적으로 다음을 수행 할 수 있습니다를 (더) :

var Employee = new Class(function() { 
    this.name = 'Unknown Employee'; 
    this.role = 'Employee'; 
}); 

var Manager = new Class({ extends: Employee }, function() 
{ 
    // Overwrite the value of 'role'. 
    this.role = 'Manager'; 

    // Class constructor to apply the given 'name' value. 
    this.__construct = function(name) { 
     this.name = name; 
    } 
}); 

var myManager = new Manager("John Smith"); 
console.log(myManager.name); // John Smith 
console.log(myManager.role); // Manager