2013-04-28 2 views
6

, 나는 항상 코드 재사용을위한 강력한 도구로 상속을 사용 Javascript가 기본적으로 상속을 지원하지 않는 이유는 무엇입니까? OOPS 기지에서 같이

예, 나는 OOPS의 체스 프로그램을 작성하고 있다면이 같은 is-a 관계,

Class Piece{ 
    int teamColor; 
    bool isLive; 
    Positon pos; 
    int Points; 
    ....... 
    int getTeamColor(){....} 
    ....... 
}; 

Class Rook extend Piece{ //`is-a` 
...... // No getTeamColor() definition here.. because the parent has the definition. 
}; 

Class Pawn extend Piece{ //`is-a` 
......// No getTeamColor() definition here.. because the parent has the definition. 
}; 

I를 구현할 때 has-a 자바 스크립트에서 관계를 할 수 있지만, 내가 볼 수있는 단점은 너무 파생 된 클래스의 모든 함수를 재정의해야합니다.

예 : getTeamColor의 재정의() 다시 모든 루크, 기사, 전당포, 왕의 .... 등

내 질문은
 var Pawn = function(teamColor,pos){ 
    var piece = new Piece(teamColor,pos); 
    ....... 

    this.getTeamColor = function(){   
      return piece.getTeamColor(); 
    }; 
    } 

입니다 , 왜 자바 스크립트 doesnot 기본 옵션으로 고전 상속을 지원 ?

+0

jOOPL (http://joopl.codeplex.com)을 살펴보십시오. 클래스 기반 OOP를 지원하도록 언어를 향상시키는 100 % JavaScript 객체 지향 라이브러리입니다. 따라서, 상속 및 다형성 (및 더 많은 기능)이 있습니다. 몇 일 안에 새로운 버전을 출시 할 예정입니다. –

+6

JavaScript는 상속을 지원합니다 *. "JavaScript prototype chain"을 찾으십시오. "javascript가 기본 옵션으로 클래식 상속을 지원하지 않는 이유는 무엇입니까?" - 이것이 자바 스크립트가 정의 된 방식이기 때문입니다. 왜 자바는 Traits를 가지고 있지 않지만 Scala는 그렇게합니까? Ruby가 아니더라도 Python이 MI를 지원하는 이유는 무엇입니까? Dylan이 C++에 여러 번 발송하는 이유는 무엇입니까? 왜 Eiffel은 LSP의 중단을 허용합니까? 글쎄요, 그들은 다른 언어 *이고 하나는 적절하다고 주장합니다 - 간접적 인 "고전적"수단을 통해 - 다른 접근법이 유효하거나 그 이상으로 유효하다는 것을 부정하는 것입니다. – user2246674

+0

javascript 개체 모델에 대한 세부 정보는 Mozilla 개발자 네트워크의 전체 기사를 참조하십시오. [여기에 링크] (https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model). 이 기사에서는 Java (클래스 기반)와 Javascript (프로토 타입 기반)를 비교하면서 상속, 계층 구조 및 관계를 다룹니다. –

답변

13

자바 스크립트는 프로토 타입 방법에 지원 상속을한다. 여기서 당신이 필요로하는 것은 클래스가 아니라 행동의 캡슐화와 재정의 능력입니다.

function Piece() { } 

Piece.prototype.color = "white"; 
Piece.prototype.getColor = function() { return this.color } 
Piece.prototype.move = function() { throw "pure function" }; 

function Pawn() { } 
Pawn.prototype = new Piece();  
Pawn.prototype.move = function() { alert("moved"); } 

지금 :

var p = new Pawn(); p.color = "black"; 

> p instanceof Piece 

사실

p instanceof Pawn 

사실

p.getColor() 

"블랙"

p.move() 

경고 ...

이 기본적인 접근 방식과 수업을 원하는 사람에 익숙한 무언가로이 차례 밖에 많은 도서관이있다 - 그렇게 말한다. 당신이 (더 캡슐화 방법으로 이전을 쓸 수 JayData와 예를 들어

체인까지 자동 생성자 호출의 보너스 :

var Piece = $data.Base.extend("Piece", { 
    move: function() { throw "pure class" } 
}); 

var Pawn = Piece.extend("Pawn", { 
    move: function() { ... } 
}); 

var p = new Pawn(); 
7

자바는 class-based object-oriented language이 아니기 때문에 prototypal입니다. 그것은 단순히 디자인 결정입니다.

또한 Javascript는 오늘날 우리가 Node.js에서 ASM.js로하는 모든 작업에 대해 결코 의미가 없습니다. 여전히 관련성이 있다는 사실은 Brendan Eich and Co.의 증언입니다. 따라서 X 또는 Y가 JS에서 구현 된 적이없는 이유를 궁금해 할 수 있습니다.하지만 사실은 20 년 전에 예상 할 수 없었던 일에 JS를 사용한다는 것입니다.

1

다양한 전통적인 OO 언어 (Java, C# 및 C++ 포함)에 대한 많은 훌륭한 책에서는 가능하면 "구현 상속"사용을 권장하지 않습니다. 예 : Joshua Bloch의 효과적인 Java

이상한 사실은 구현 상속이 코드에 규칙적인 "모양"을주는 것처럼 보이지만 문제를 해결하는 데 도움이되지 않는다는 것입니다. 종종 문제가 장기적으로 발생합니다.

저 작성자는 "상속 인터페이스"대신에 축복을주는 경향이 있지만 JavaScript와 같은 오리 유형 언어에서는 명시 적으로 그러한 상속을 선언 할 필요가 없습니다.

그리고 JS에서는 동일한 기능을 여러 객체의 속성으로 간단히 할당하여 "재사용"할 수 있습니다. 당신이 필요로하는 상속의 풍미가 무엇이든간에, 당신은 그것을 아무 것도 상상할 수 없습니다.

1

JavaScript에는 실제 OOP 스타일 클래스가 없기 때문에 비슷한 것을 시뮬레이션 할 수 있습니다. 당신의 예에서

, 당신은

var Pawn = function(teamColor, pos) { 
    Piece.call(this, teamColor, pos); 
} 

그러나, 당신은 일반적으로 오히려 새로운 생성 된 객체에 대한보다 기능 프로토 타입에 대한 방법을 첨부해야한다 수행하여 상속을 달성 할 수있다. 커피 스크립트가 그것을하는 것처럼이 경우에는, 예를 들면, 프로토 타입 체인을 설정하여 상속을 시뮬레이션 할 수 있습니다 :

var a, b, _ref, 
    __hasProp = {}.hasOwnProperty, 
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 

a = (function() { 
    function a() {} 

    return a; 

})(); 

b = (function(_super) { 
    __extends(b, _super); 

    function b() { 
    _ref = b.__super__.constructor.apply(this, arguments); 
    return _ref; 
    } 

    return b; 

})(a); 
+4

이것은 필요한 작업을 위해 imho overkill (과 약간 횡설수설)입니다. 즉, 클래스 트리 아래에서 동작을 무시합니다. –

0

다음 코드 블록은에서 하나의 자바 스크립트 프로토 타입을 "확장"됩니다 다른하고, "instanceof를"연산자는 기본 및 파생 클래스에 대해 올바르게 작동하는지 확인합니다. 나는 "instanceof를"연산자의 논리적 일관성 때문 위해 할 수있는 새로운하여 TestA로를 TestB의 프로토 타입을 설정, 무엇을 말할 수에서

을.

이것을 TestA에 전달하면 새로운 인스턴스에 원하는 모든 속성과 메서드가 제공됩니다.

이런 식으로하는 것은 문체적인 욕망과 실용적인 욕구 사이의 일종의 균형입니다. 이것은 대부분의 브라우저에서 작동하며 심지어 강제로 지원하는 경우 Internet Explorer에서도 작동합니다. 또한 동일한 블록에 포함 된 메소드를 기존 OO 구문과 매우 흡사하기 때문에 도움이됩니다.

JavaScript가 OO의 전통적인 스타일을 지원하지 않는 주된 이유는 창립 철학 때문입니다. 건국 철학은 자유입니다. 이 자유는 개발자가 자신의 스타일을 프로젝트의 필요에 맞게 설계 할 수 있도록하기위한 것입니다.

function TestA(){ 
    var me = this; 

    me.method = function(){ 
    } 
} 

function TestB(){ 
    TestA.call(this); 
    var me = this; 

    me.otherMethod = function(){ 
    } 
} 
TestB.prototype = new TestA(); 

var test = new TestB(); 

console.log(test); 

console.log(test instanceof TestB); 
console.log(test instanceof TestA); 

//TestA { method: [Function], otherMethod: [Function] } 
//true 
//true 
관련 문제