클래식에 비해 프로토 타입 상속의 이점은 무엇입니까?


271

그래서 나는 마침내 몇 년 동안 내 발 끌기를 멈추고 JavaScript를 "적절하게"배우기로 결정했습니다. 언어 디자인에서 가장 머리를 긁는 요소 중 하나는 상속 구현입니다. Ruby에서 경험을 쌓은 후 클로저와 동적 타이핑을 보게되어 정말 기뻤습니다. 그러나 내 인생에서 상속을 위해 다른 인스턴스를 사용하여 객체 인스턴스에서 어떤 이점이 있는지 알아낼 수 없습니다.



답변:


560

나는이 답변이 3 년 늦었다는 것을 알고 있지만, 현재 답변이 프로토 타입 상속이 클래식 상속보다 얼마나 좋은지에 대한 충분한 정보를 제공하지 못한다고 생각합니다 .

먼저 프로토 타입 상속을 방어 할 때 JavaScript 프로그래머가 언급하는 가장 일반적인 논증을 살펴 보자 (현재 논란에서이 논증을 취하고있다).

  1. 간단 해.
  2. 강력합니다.
  3. 더 작고 적은 중복 코드로 이어집니다.
  4. 동적이므로 동적 언어에 적합합니다.

이제 이러한 주장은 모두 유효하지만 아무도 이유를 설명하지 않았습니다. 어린이에게 수학 공부가 중요하다고 말하는 것과 같습니다. 물론이지만, 아이는 확실히 신경 쓰지 않습니다. 중요하다고 말함으로써 수학과 같은 아이를 만들 수 없습니다.

프로토 타입 상속의 문제점은 JavaScript의 관점에서 설명된다는 것입니다. JavaScript를 좋아하지만 JavaScript의 프로토 타입 상속이 잘못되었습니다. 고전 상속과 달리 프로토 타입 상속에는 두 가지 패턴이 있습니다.

  1. 프로토 타입 상속의 프로토 타입 패턴.
  2. 프로토 타입 상속의 생성자 패턴.

불행히도 JavaScript는 프로토 타입 상속의 생성자 패턴을 사용합니다. 이것은 JavaScript가 만들어 졌을 때 (JS의 제작자 인) Brendan Eich가 Java (고전 상속이있는)처럼 보이기를 원했기 때문입니다.

우리는 Visual Basic과 같은 보완 언어가 당시 Microsoft의 언어 패밀리에서 C ++로 사용 되었기 때문에 Java의 동생으로 밀어 붙였습니다.

사람들이 JavaScript에서 생성자를 사용할 때 생성자가 다른 생성자로부터 상속받는 것으로 생각하기 때문에 이것은 나쁘다. 이것은 잘못이다. 프로토 타입 상속에서 객체는 다른 객체로부터 상속됩니다. 생성자는 결코 그림에 들어오지 않습니다. 이것이 대부분의 사람들을 혼란스럽게하는 것입니다.

고전적인 상속 기능을 가진 Java와 같은 언어를 사용하는 사람들은 생성자가 클래스처럼 보이지만 클래스처럼 동작하지 않기 때문에 더욱 혼란스러워집니다. 로 더글러스 크록 포드는 말했다 :

이 간접적 인 의도는 언어를 고전적으로 훈련 된 프로그래머에게 친숙하게 보이도록하기위한 것이지만 Java 프로그래머가 JavaScript에 대해 매우 낮은 견해에서 볼 수 있듯이 그렇게하지 못했습니다. JavaScript의 생성자 패턴은 고전적인 군중에게는 호소력이 없었습니다. 또한 JavaScript의 진정한 프로토 타입 특성을가 렸습니다. 결과적으로 언어를 효과적으로 사용하는 방법을 아는 프로그래머는 거의 없습니다.

거기 있어요 말의 입에서 곧장.

진정한 프로토 타입 상속

프로토 타입 상속은 객체에 관한 것입니다. 객체는 다른 객체의 속성을 상속합니다. 그것이 전부입니다. 프로토 타입 상속을 사용하여 오브젝트를 작성하는 두 가지 방법이 있습니다.

  1. 새로운 개체를 만듭니다.
  2. 기존 객체를 복제하고 확장합니다.

참고 : JavaScript는 객체 위임연결 을 복제하는 두 가지 방법을 제공합니다 . 이제부터는 "복제"라는 단어를 사용하여 위임을 통한 상속을 독점적으로, "복사"라는 단어를 사용하여 연결을 통한 상속을 독점적으로 언급합니다.

충분한 이야기. 몇 가지 예를 봅시다. 반경의 원이 있다고 가정 해보십시오 5.

var circle = {
    radius: 5
};

반지름으로부터 원의 면적과 원주를 계산할 수 있습니다.

circle.area = function () {
    var radius = this.radius;
    return Math.PI * radius * radius;
};

circle.circumference = function () {
    return 2 * Math.PI * this.radius;
};

이제 다른 반경의 원을 만들고 싶습니다 10. 이를 수행하는 한 가지 방법은 다음과 같습니다.

var circle2 = {
    radius: 10,
    area: circle.area,
    circumference: circle.circumference
};

그러나 JavaScript는 더 나은 방법 위임을 제공합니다 . 이 Object.create기능은 다음을 수행하는 데 사용됩니다.

var circle2 = Object.create(circle);
circle2.radius = 10;

그게 다야. JavaScript에서 프로토 타입 상속을 수행했습니다. 그렇게 간단하지 않습니까? 객체를 가져 와서 복제하고, 필요한 것을 변경하고, 자신에게 새로운 객체를 얻었습니다.

이제 "이것은 얼마나 간단합니까? 새 원을 만들 때마다 복제 circle하고 수동으로 반지름을 지정해야합니다"라고 물을 수 있습니다. 해결책은 무거운 물건을 들어 올리는 기능을 사용하는 것입니다.

function createCircle(radius) {
    var newCircle = Object.create(circle);
    newCircle.radius = radius;
    return newCircle;
}

var circle2 = createCircle(10);

실제로 다음과 같이이 모든 것을 단일 객체 리터럴로 결합 할 수 있습니다.

var circle = {
    radius: 5,
    create: function (radius) {
        var circle = Object.create(this);
        circle.radius = radius;
        return circle;
    },
    area: function () {
        var radius = this.radius;
        return Math.PI * radius * radius;
    },
    circumference: function () {
        return 2 * Math.PI * this.radius;
    }
};

var circle2 = circle.create(10);

JavaScript의 프로토 타입 상속

위 프로그램 create에서이 함수는의 복제본을 만들고 circle새 복제본을 할당 한 radius다음 반환합니다. 이것이 바로 JavaScript에서 생성자가하는 일입니다.

function Circle(radius) {
    this.radius = radius;
}

Circle.prototype.area = function () {
    var radius = this.radius;
    return Math.PI * radius * radius;
};

Circle.prototype.circumference = function () {         
    return 2 * Math.PI * this.radius;
};

var circle = new Circle(5);
var circle2 = new Circle(10);

JavaScript의 생성자 패턴은 반전 된 프로토 타입 패턴입니다. 객체를 생성하는 대신 생성자를 생성합니다. new키워드는 결합 this의 복제에 생성자 내부 포인터를 prototype생성자.

혼란스러워? JavaScript의 생성자 패턴이 불필요하게 복잡하기 때문입니다. 이것은 대부분의 프로그래머가 이해하기 어려운 것입니다.

그들은 다른 객체로부터 상속받은 객체를 생각하는 대신 다른 생성자로부터 상속받은 생성자를 생각하고 완전히 혼란스러워합니다.

JavaScript의 생성자 패턴을 피해야하는 다른 많은 이유가 있습니다. 내 블로그 게시물에서 그 내용을 읽을 수 있습니다 : 생성자 대 프로토 타입


그렇다면 고전 상속에 비해 프로토 타입 상속의 이점은 무엇입니까? 가장 일반적인 논증을 다시 살펴보고 왜 그런지 설명해 봅시다 .

1. 프로토 타입 상속은 간단합니다

CMS 는 그의 답변에서 다음과 같이 말합니다.

제 생각에, 프로토 타입 상속의 주요 이점은 단순성입니다.

우리가 방금 한 일을 생각해 봅시다. circle반지름이 반지름 인 객체 를 만들었습니다 5. 그런 다음 복제하여 반지름을으로 지정했습니다 10.

따라서 우리는 프로토 타입 상속 작업을하기 위해 두 가지만 필요합니다 :

  1. 새로운 객체를 만드는 방법 (예 : 객체 리터럴).
  2. 기존 객체를 확장하는 방법 (예 :) Object.create.

반대로 고전 상속은 훨씬 더 복잡합니다. 고전 상속에는 다음이 있습니다.

  1. 클래스.
  2. 목적.
  3. 인터페이스.
  4. 추상 클래스.
  5. 최종 수업.
  6. 가상 기본 클래스.
  7. 생성자.
  8. 소멸자.

당신은 아이디어를 얻습니다. 요점은 프로토 타입 상속이 이해하기 쉽고 구현하기 쉽고 추론하기 쉽다는 것입니다.

Steve Yegge가 자신의 고전 블로그 게시물 " Portrait of a N00b "에 다음 과 같이 덧붙였습니다

메타 데이터는 다른 종류의 설명이나 모델입니다. 코드의 주석은 계산에 대한 자연어 설명입니다. 메타 데이터를 메타 데이터로 만드는 것은 반드시 필요하지 않다는 것입니다. 가계 서류가있는 개가 있는데 서류를 잃어버린 경우에도 여전히 완벽하게 유효한 개가 있습니다.

같은 의미에서 클래스는 단지 메타 데이터입니다. 상속에 클래스가 반드시 필요한 것은 아닙니다. 그러나 일부 사람들 (보통 n00bs)은 수업에 더 편한 수업을 찾습니다. 그것은 잘못된 보안 감각을 제공합니다.

정적 유형은 메타 데이터 일 뿐이라는 것도 알고 있습니다. 프로그래머와 컴파일러라는 두 종류의 독자를 대상으로하는 특수한 종류의 주석입니다. 정적 유형은 두 독자 그룹이 프로그램의 의도를 이해하도록 돕기 위해 계산에 대한 이야기를 들려줍니다. 그러나 정적 유형은 런타임에 폐기 될 수 있습니다. 결국에는 양식화 된 주석 일뿐입니다. 그들은 가계도 서류와 같습니다. 개에 대해 안전하지 않은 성격 유형을 더 행복하게 만들 수 있지만 개는 확실히 신경 쓰지 않습니다.

앞서 언급했듯이 수업은 사람들에게 잘못된 보안 감각을 부여합니다. 예를 들어 NullPointerException코드를 완벽하게 읽을 수있는 경우에도 Java에서 너무 많은 값을 얻습니다 . 고전적인 상속은 일반적으로 프로그래밍 방식으로 이루어 지지만 Java 일뿐입니다. 파이썬에는 놀라운 고전 상속 시스템이 있습니다.

2. 프로토 타입 상속은 강력합니다

고전적 배경에서 온 대부분의 프로그래머는 고전적 상속이 프로토 타입 상속보다 강력하다고 주장합니다.

  1. 개인 변수.
  2. 다중 상속.

이 주장은 허위입니다. 우리는 이미 JavaScript가 클로저를 통해 개인 변수를 지원한다는 것을 알고 있지만 다중 상속은 어떻습니까? JavaScript의 객체에는 하나의 프로토 타입 만 있습니다.

진실은 프로토 타입 상속이 여러 프로토 타입에서 상속을 지원한다는 것입니다. 프로토 타입 상속은 단순히 하나의 객체가 다른 객체로부터 상속됨을 의미합니다. 실제로 프로토 타입 상속을 구현하는 두 가지 방법 이 있습니다 .

  1. 위임 또는 차등 상속
  2. 클로닝 또는 연결 상속

예 JavaScript는 객체가 다른 객체에만 위임 할 수 있도록합니다. 그러나 임의 수의 객체 속성을 복사 할 수 있습니다. 예를 _.extend들어이 작업을 수행합니다.

물론 많은 프로그래머가이 사실 상속으로 간주하지 아니한다 때문에 instanceof와는 isPrototypeOf달리 말한다. 그러나 이는 연결을 통해 프로토 타입에서 상속되는 모든 객체에 프로토 타입 배열을 저장하여 쉽게 해결할 수 있습니다.

function copyOf(object, prototype) {
    var prototypes = object.prototypes;
    var prototypeOf = Object.isPrototypeOf;
    return prototypes.indexOf(prototype) >= 0 ||
        prototypes.some(prototypeOf, prototype);
}

따라서 프로토 타입 상속은 클래식 상속만큼 강력합니다. 실제로 프로토 타입 상속에서는 복사 할 속성과 다른 프로토 타입에서 생략 할 속성을 직접 선택할 수 있기 때문에 클래식 상속보다 훨씬 강력합니다.

고전적인 상속에서는 상속하려는 속성을 선택하는 것이 불가능합니다 (또는 적어도 매우 어렵습니다). 그들은 가상 문제 를 해결하기 위해 가상 기본 클래스와 인터페이스를 사용 합니다.

그러나 JavaScript에서는 상속하려는 속성과 프로토 타입을 정확하게 제어 할 수 있기 때문에 다이아몬드 문제에 대해 전혀 듣지 못할 것입니다.

3. 프로토 타입 상속은 덜 중복 적입니다

고전적 상속이 반드시 더 많은 중복 코드로 이어지지는 않기 때문에이 점을 설명하기가 조금 더 어렵습니다. 사실 고전이든 프로토 타입이든 상속은 코드의 중복성을 줄이기 위해 사용됩니다.

하나의 주장은 고전 상속이있는 대부분의 프로그래밍 언어는 정적으로 유형이 지정되며 암시 적 정적 유형을 갖는 Haskell과 달리 사용자가 유형을 명시 적으로 선언해야한다는 것입니다. 따라서 더 자세한 코드가 생성됩니다.

Java는이 동작으로 유명합니다. 나는 Bob Nystrom이 Pratt Parsers 에 대한 그의 블로그 포스트에서 다음의 일화를 언급 한 것을 분명히 기억합니다 .

Java의 "4 배로 서명하십시오"수준의 관료주의를 좋아해야합니다.

다시 말하지만, Java가 너무 빨라서 그럴 것이라고 생각합니다.

하나의 유효한 주장은 고전적 상속을 가진 모든 언어가 다중 상속을 지원하지는 않는다는 것입니다. 다시 자바가 떠오른다. 예 Java에는 인터페이스가 있지만 충분하지 않습니다. 때로는 다중 상속이 필요합니다.

프로토 타입 상속은 다중 상속을 허용하므로 다중 상속이 필요한 코드는 고전 상속은 있지만 다중 상속은없는 언어가 아닌 프로토 타입 상속을 사용하여 작성하면 덜 중복됩니다.

4. 프로토 타입 상속은 동적이다

프로토 타입 상속의 가장 중요한 장점 중 하나는 프로토 타입을 만든 후 프로토 타입에 새 속성을 추가 할 수 있다는 것입니다. 이를 통해 프로토 타입에 새로운 메소드를 추가 할 수 있으며,이 메소드는 해당 프로토 타입에 위임 된 모든 객체에 자동으로 제공됩니다.

클래스를 만든 후에는 런타임에 클래스를 수정할 수 없으므로 클래식 상속에서는 불가능합니다. 이것은 아마도 고전 상속에 비해 프로토 타입 상속의 가장 큰 장점 일 것입니다. 그러나 나는 결국 최선을 다하는 것을 좋아합니다.

결론

프로토 타입 상속이 중요합니다. 프로토 타입 상속의 프로토 타입 패턴을 선호하여 프로토 타입 상속의 생성자 패턴을 포기해야하는 이유에 대해 JavaScript 프로그래머에게 교육하는 것이 중요합니다.

JavaScript를 올바르게 가르치기 시작하면 새로운 프로그래머에게 생성자 패턴 대신 프로토 타입 패턴을 사용하여 코드를 작성하는 방법을 보여줄 수 있습니다.

프로토 타입 패턴을 사용하여 프로토 타입 상속을 설명하는 것이 더 쉬울뿐만 아니라 더 나은 프로그래머가 될 것입니다.

이 답변이 마음에 들면 " Prototypal Inheritance Matters " 에 대한 내 블로그 게시물을 읽어보십시오 . 나를 믿어 라. 실망하지 않을 것이다.


33
나는 당신이 어디에서 왔는지 이해하고, 프로토 타입 상속이 매우 유용하다는 데 동의하지만, 나는 "프로토 타입 상속이 클래식 상속보다 낫다"라는 가정을함으로써 이미 실패 할 것이라고 생각합니다. 당신에게 약간의 관점을주기 위해, 나의 라이브러리 jTypes는 JavaScript를위한 고전적인 상속 라이브러리입니다. 그래서 그것을 만드는 데 시간이 걸렸던 사람 이여, 나는 여전히 여기 앉아서 프로토 타입 상속이 대단하고 매우 유용하다고 말할 것입니다. 그러나 이것은 프로그래머가 가지고있는 많은 도구 중 하나 일뿐입니다. 프로토 타입 상속에도 여전히 많은 단점이 있습니다.
레드 라인

7
나는 당신이 말한 것에 완전히 동의합니다. 너무 많은 프로그래머가 고전 상속이 없기 때문에 JavaScript를 거부하거나 단순하고 멍청한 언어로 그것을 비난한다고 생각합니다. 실제로는 매우 강력한 개념이며 동의합니다. 많은 프로그래머가이를 받아들이고 배워야합니다. 그 말로, 나는 JavaScript에 존재하는 모든 형태의 고전 상속에 반대하는 JavaScript의 개발자가 실제로 있다고 주장합니다. 둘 다 자신의 권리가 똑같이 강력하고 똑같이 유용합니다.
레드 라인

9
글쎄, 그것은 당신의 의견이지만, 나는 계속 동의하지 않을 것이며, CoffeeScript 및 TypeScript와 같은 것들의 인기가 높아짐에 따라 적절한 경우이 기능을 사용하려는 개발자 커뮤니티가 많이 있음을 알 수 있다고 생각합니다. 말했듯이 ES6는 구문 설탕을 추가하지만 jTypes의 광범위 성을 제공하지는 않습니다. 참고로, 나는 당신의 downvote를 책임지는 사람이 아닙니다. 나는 당신에 동의하지 않지만, 그것이 당신이 나쁜 대답을했다고 생각하지는 않습니다. 당신은 매우 철저했습니다.
레드 라인

25
당신은 단어 복제 를 많이 사용 하고 있습니다. Object.create지정된 프로토 타입으로 새 오브젝트를 작성 중입니다. 선택한 단어는 프로토 타입이 복제되었다는 인상을줍니다.
Pavel Horal

7
@Aadit : 정말 방어적일 필요는 없습니다. 귀하의 답변은 매우 상세하며 투표 할 가치가 있습니다. "linked"가 "clone"의 드롭 인 대체물이어야한다고 제안하는 것이 아니라 "clone"이라는 용어에 대한 자신의 정의를 주장하는지 여부에 관계없이 개체와 개체가 상속하는 프로토 타입 간의 연결을보다 적절하게 설명해야합니다. "또는 아닙니다. 변경하거나 변경하지 마십시오. 전적으로 귀하의 선택입니다.
Andy E

42

실제로 인라인으로 질문에 대답하겠습니다.

프로토 타입 상속에는 다음과 같은 장점이 있습니다.

  1. 상속이 환경과 같이 동적이기 때문에 동적 언어에 더 적합합니다. (여기서는 JavaScript에 적용 할 수 있어야합니다.) 이렇게하면 대량의 인프라 코드없이 클래스를 사용자 정의하는 것처럼 신속하게 작업을 수행 할 수 있습니다. .
  2. 고전적인 클래스 / 객체 이분법 체계보다 프로토 타입 제작 체계를 구현하는 것이 더 쉽습니다.
  3. "메타 클래스 (Metaclasses)"(메타 클래스를 절대 좋아하지 않습니다 ... 미안합니다!) 또는 "고유 값"과 같은 개체 모델 주위의 복잡한 날카로운 모서리가 필요 없습니다.

그러나 다음과 같은 단점이 있습니다.

  1. 프로토 타입 언어의 타입 검사는 불가능하지는 않지만 매우 어렵습니다. 프로토 타입 언어의 대부분의 "유형 검사"는 순수한 런타임 "덕 타이핑"스타일 검사입니다. 모든 환경에 적합한 것은 아닙니다.
  2. 정적 분석 (또는 종종 동적 분석)으로 메소드 디스패치 최적화와 같은 작업을 수행하는 것도 마찬가지로 어렵습니다. 그것은 (나는 스트레스 : ) 아주 쉽게 매우 비효율적이다.
  3. 유사하게 객체 생성은 더 일반적인 클래스 / 객체 이분법에서보다 프로토 타입 언어에서 훨씬 느릴 수 있습니다.

위의 줄을 읽고 전통적인 클래스 / 객체 체계의 해당 장단점을 생각해 볼 수 있다고 생각합니다. 물론 각 영역에는 더 많은 것이 있으므로 나머지는 응답하는 사람들에게 맡기십시오.


1
팬보이가 아닌 간결한 답변입니다. 이것이 이것이 질문에 대한 최고의 답변이기를 바랍니다.
siliconrockstar

현재 코드가 컴파일되는 동안 코드를 컴파일 할 수있는 Dynamic Just-in-Time 컴파일러가 있으며 각 섹션마다 다른 코드 조각을 만듭니다. 자바 스크립트는 실제로 프로토 타입을 사용하더라도 최적화에 많은 작업이 수행 되었기 때문에 클래식 클래스를 사용하는 Ruby 나 Python보다 빠릅니다.
aoeu256

28

프로토 타입 상속의 주요 이점 인 IMO는 단순성입니다.

언어의 원형은 고전적으로 훈련받은 사람들을 혼란스럽게 할 수 있지만 실제로 이것은 실제로 단순하고 강력한 개념, 차등 상속 이라는 것이 밝혀졌습니다 .

분류 할 필요가 없으며 코드가 작고 중복성이 적으며 객체는 다른 일반적인 객체에서 상속됩니다.

프로토 타입으로 생각 하면 곧 수업이 필요하지 않다는 것을 알게 될 것입니다 ...

ECMAScript 5th Edition 사양 은 프로토 타입 상속이 가까운 미래에 훨씬 더 인기가있을 것입니다 Object.create.

var obj = Object.create(baseInstance);

이 새로운 버전의 표준은 모든 브라우저 공급 업체에서 구현하고 있으며 더 순수한 프로토 타입 상속을 보게 될 것입니다 ...


11
"코드가 작고 중복성이 적습니다 ..."왜? "차등 상속"에 대한 Wikipedia 링크를 살펴 보았으며 이러한 주장을 뒷받침하는 것은 없습니다. 고전적인 상속으로 인해 더 크고 더 많은 중복 코드가 생성되는 이유는 무엇입니까?
노엘 아브라함

4
정확히, 나는 노엘에 동의합니다. 프로토 타입 상속은 단순히 작업을 수행하는 한 가지 방법이지만 올바른 방법이 아닙니다. 다른 도구는 다른 작업에 대해 다른 방식으로 수행됩니다. 프로토 타입 상속이 그 자리에 있습니다. 매우 강력하고 간단한 개념입니다. 그러나 캡슐화와 다형성에 대한 지원이 부족하면 JavaScript가 큰 단점이됩니다. 이러한 방법론은 JavaScript보다 훨씬 길 었으며, 교장의 견해는 양호합니다. 따라서 프로토 타입이 더 낫다고 생각하는 것은 잘못된 생각입니다.
레드 라인

1
프로토 타입 기반 상속을 사용하여 클래스 기반 상속을 시뮬레이션 할 수 있지만 그 반대도 마찬가지입니다. 좋은 주장 일 수 있습니다. 또한 캡슐화는 언어 기능보다 규칙으로 간주됩니다 (일반적으로 리플렉션을 통해 캡슐화를 중단 할 수 있음). 다형성에 관해서-메소드 인수를 확인할 때 간단한 "if"조건을 작성할 필요가 없습니다 (컴파일 중에 대상 메소드가 해결되면 약간의 속도). 여기에는 실제 JavaScript 단점이 없습니다.
Pavel Horal

프로토 타입은 훌륭합니다. IMO. Haskell과 같은 기능적 언어를 만들려고 생각하고 있지만 추상화를 만드는 대신 프로토 타입을 기반으로 모든 것을 만들 것입니다. 합을 일반화하는 대신 "계산"하기 위해 합계의 프로토 타입을 작성하고 +를 *로, 0을 1로 대체하여 제품을 만들어야합니다. 약속 / 콜백의 "then"을 "then"의 동의어 인 flatMap으로 대체하는 프로토 타입으로 "Monads"를 설명하겠습니다. 프로토 타입이 기능 프로그래밍을 대중에게 가져다 줄 수 있다고 생각합니다.
aoeu256

11

두 가지 방법 중에서 선택해야 할 것이 많지 않습니다. 파악해야 할 기본 아이디어는 JavaScript 엔진에 읽을 객체의 속성이 주어지면 먼저 인스턴스를 확인하고 해당 속성이없는 경우 프로토 타입 체인을 확인한다는 것입니다. 다음은 프로토 타입과 클래식의 차이점을 보여주는 예입니다.

프로토 타입

var single = { status: "Single" },
    princeWilliam = Object.create(single),
    cliffRichard = Object.create(single);

console.log(Object.keys(princeWilliam).length); // 0
console.log(Object.keys(cliffRichard).length); // 0

// Marriage event occurs
princeWilliam.status = "Married";

console.log(Object.keys(princeWilliam).length); // 1 (New instance property)
console.log(Object.keys(cliffRichard).length); // 0 (Still refers to prototype)

클래식 한 인스턴스 메소드 (각 인스턴스가 자체 속성을 저장하기 때문에 비효율적 임)

function Single() {
    this.status = "Single";
}

var princeWilliam = new Single(),
    cliffRichard = new Single();

console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 1

효율적인 클래식

function Single() {
}

Single.prototype.status = "Single";

var princeWilliam = new Single(),
    cliffRichard = new Single();

princeWilliam.status = "Married";

console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 0
console.log(cliffRichard.status); // "Single"

보시다시피, 고전적인 스타일로 선언 된 "클래스"프로토 타입을 조작 할 수 있기 때문에 프로토 타입 상속을 사용하면 아무런 이점이 없습니다. 고전적인 방법의 일부입니다.


2
이 주제에 대한 다른 답변과 리소스를 살펴보면 "프로토 타입 상속은 클래식 상속의 모양을 허용하기 위해 JavaScript에 추가 된 구문 설탕의 하위 집합입니다." OP는 JavaScript 내에서 인스턴스화 기술을 비교하는 대신 다른 언어의 고전 상속에 비해 JS의 프로토 타입 상속의 이점에 대해 묻고있는 것으로 보입니다.
Fader Faly Darkly

2

웹 개발 : 프로토 타입 상속과 클래식 상속

http://chamnapchhorn.blogspot.com/2009/05/prototypal-inheritance-vs-classical.html

클래식 대 프로토 타입 상속

클래식 대 프로토 타입 상속


20
다른 SO 링크가 아닌 한 링크를 붙여 넣는 대신 링크 내용을 요약하는 것이 좋습니다. 링크 / 사이트가 다운되고 질문에 대한 응답이 느슨해져 검색 결과에 영향을 줄 수 있기 때문입니다.
James Westgate

첫 번째 링크는 프로토 타입 상속인가에 대한 질문에 답하지 않습니다 간단히 설명합니다.
viebel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.