클래스 상속은 한 클래스가 다른 클래스를 확장하는 방법입니다.따라서 기존 기능 위에 새로운 기능을 만들 수 있습니다.

는”것이다:”키워드

이제 우리는 등Animal

여기에 우리는 어떻게 나타낼 수 있는animal개체고Animal클래스는 그래픽으로:

…우리를 만들고 싶은 다른class Rabbit.,

으로 토끼는 동물,Rabbit등에 기반해야 합Animal에 액세스하여 동물의 방법,그래서는 토끼 무엇을 할 수 있는”일반적인”동물을 할 수 있습니다.

다른 클래스를 확장하는 구문은 다음과 같습니다.class Child extends Parent.

자 만들기class Rabbit에서 상속되는Animal

체의Rabbit클래스가 모두에 액세스하는Rabbit방법,같은rabbit.hide(), 또한Animal방법,같은rabbit.run().,

내부적으로extends키워드는 좋은 오래된 프로토 타입 역학을 사용하여 작동합니다. 그것은Rabbit.prototype.]Animal.prototype로 설정합니다. 따라서Rabbit.prototype에서 메서드를 찾을 수없는 경우 JavaScript 는Animal.prototype에서 가져옵니다.,

예를 들어,을 찾rabbit.run방법 엔진 검사(아래 그림):

우리가 할 수있는 기억에서 장을 기본 프로토타입,자바 스크립트 자체를 사용 prototypal 상속에 대한 내 개체입니다. 예를 들어Date.prototype.]Object.prototype입니다. 이것이 날짜가 일반 객체 메소드에 액세스 할 수있는 이유입니다.,

어떤 식 허용 후extends

클래스 구문을 허용하 지정하려면 단지 클래스,그러나 어떤 표현한 후extends.

예를 들어,함수 호출을 생성하는 부모 클래스:

function f(phrase) { return class { sayHi() { alert(phrase); } };}class User extends f("Hello") {}new User().sayHi(); // Hello

여기에는class User에서 상속한 결과는f("Hello").,

용으로 사용할 수 있는 고급 프로그래밍 패턴을 때 우리가 사용하는 기능을 생성하는 클래스에 따라 많은 조건에서 상속할 수 있습니다.메서드를 재정의하는 방법은 다음과 같습니다. 기본적으로 모든 방법에서 지정하지 않은class Rabbit은 직접 촬영에서”있는 그대로”class Animal.,

그러나 우리가 지정하는 우리 자신의 방법에서Rabbit,같은stop()다음에 그것을 사용자 정의할 수 있습니다:

class Rabbit extends Animal { stop() { // ...now this will be used for rabbit.stop() // instead of stop() from class Animal }}

일반적으로 우리가 원하지 않을 완전히 바꾸는 부모는 방법이지만,오히려 구축을 위에 그것의 조정 또는 확장 기능이 있습니다. 우리는 우리의 메소드에서 무언가를 수행하지만,그 전/후에 또는 그 과정에서 부모 메소드를 호출합니다.

클래스는"super"키워드를 제공합니다.부모 메서드를 호출하려면”9927b6b093″>

id=”9927b6b093″>

  • .,
  • super(...)부모 생성자를 호출합니다(생성자 내부에서만).

예를 들어,우리의 토끼 자동 숨기기 멈췄을 때:

지금Rabbitstop메소드를 호출하는 부모super.stop()에서 처리합니다.

생성자 재정의

생성자를 사용하면 조금 까다로워집니다.

지금까지Rabbit는 자체constructor가 없었습니다.,

사양에 따라 경우,클래스가 다른 클래스를 확장하고 있지 않constructor,다음”empty”constructor이 생성됩니다:

class Rabbit extends Animal { // generated for extending classes without own constructors constructor(...args) { super(...args); }}

우리가 볼 수있는 바와 같이, 그것은 기본적으로 통화 부모constructor전달하는 모든 인수입니다. 우리가 우리 자신의 생성자를 작성하지 않으면 발생합니다.이제

이제Rabbit에 사용자 정의 생성자를 추가하겠습니다. 그것은earLength외에name를 지정합니다:

Whoops!, 우리는 오류가 있습니다. 이제 우리는 토끼를 만들 수 없습니다. 무엇이 잘못 되었습니까?

짧은 대답은 다음과 같습니다.

  • 상속 클래스의 생성자는super(...)를 호출해야하며(!)this를 사용하기 전에 수행하십시오.

…하지만 왜? 무슨 일이야? 실제로 요구 사항은 이상하게 보입니다.

물론 설명이 있습니다. 자의 세부 사항으로,그래서 당신은 정말 무슨 일이 일어나고 있는지 이해한다.

JavaScript 에서는 상속 클래스의 생성자 함수(소위”파생 생성자”)와 다른 함수 사이에 구분이 있습니다., 파생 생성자에는 특별한 내부 속성]:"derived"가 있습니다. 그것은 특별한 내부 라벨입니다.

해당 레이블은new의 동작에 영향을줍니다.

  • 정규 함수가new로 실행되면 빈 객체를 만들어this에 할당합니다.
  • 그러나 파생 된 생성자가 실행되면이를 수행하지 않습니다. 부모 생성자가이 작업을 수행 할 것으로 기대합니다.,

그 파생 생성자를 호출해야 합super를 실행하기 위해서는 부모(베이스)생성자,그렇지 않으면 개체 위해this이 생성되지 않습니다. 그리고 우리는 오류가 발생합니다.

에 대해Rabbit생성자를 작업,그것은 필요가 전화super()을 사용하기 전에this,다음과 같은 여기:

재정의하는 등 필드: 까다로운 주

고급 주

이 주의서 당신은 특정한 경험과 함께 클래스고,어쩌면에서 다른 프로그래밍 언어입니다.,

언어에 대한 더 나은 통찰력을 제공하고 버그의 원천이 될 수있는 동작을 설명합니다(자주는 아니지만).

경우에 당신은 그것을 찾을 이해하기 어려운,그냥 계속 읽을 다음,반환을 그것은 몇 시간을 보내시길 바랍니다.

메소드뿐만 아니라 클래스 필드도 재정의 할 수 있습니다.

있지만,거기에 까다로운 행동을 때 우리에 액세스를 재정의 필드에서 부모를 생성자,매우 다양에서 대부분의 다른 프로그래밍 언어입니다.,

다음 예제를 살펴보십시오:

여기에,classRabbit연장Animal과 재정의name필드 그것의 자신의 값입니다.

Rabbit에 자체 생성자가 없으므로Animal생성자가 호출됩니다.

흥미로운 것은 두 가지 경우 모두에서:new Animal()new Rabbit(),alert줄에는(*)animal.,즉,부모 생성자는 항상 재정의 된 필드 값이 아닌 자체 필드 값을 사용합니다.

그것에 대해 이상한 점은 무엇입니까?아직 명확하지 않은 경우 메소드와 비교하십시오.

여기에는 동일한 코드,하지만 그 대신this.name필리this.showName()방법:

참고:지금은 출력이 다르다.이것이 우리가 자연스럽게 기대하는 것입니다. 파생 클래스에서 상위 생성자가 호출되면 재정의 된 메서드를 사용합니다.그러나 클래스 필드의 경우 그렇지 않습니다. 말했듯이 부모 생성자는 항상 부모 필드를 사용합니다.,

왜 차이가 있습니까?그 이유는 필드 초기화 순서에 있습니다. 클래스 분야의 초기화:

  • 기 전에 생성자를 위한 기본 클래스(지 않는 확장을 아무거나),
  • 후 즉시super()파생된 클래스입니다.

우리의 경우Rabbit는 파생 클래스입니다. 거기에constructor()가 없습니다. 앞에서 말했듯이super(...args)만있는 빈 생성자가있는 경우와 같습니다.,

new Rabbit()통화super(),따라서 실행하는 부모를 생성자,그리고(당 규칙에 대한 파생된 클래스)만 그 후에 그것의 등 필드를 초기화해야 합니다. 시간에 부모의 생성자를 실행이 없는Rabbit등 필드를 아직,그 이유는Animal필드에 사용됩니다.

이 미묘한 차이 분야와 방법에 특정 자바 스크립트

다행히도,이 동작은 경우에만 자신을 드러내는 경우는 재정의 필드에 사용되는 부모가 생성자입니다., 그렇다면 무슨 일이 벌어지고 있는지 이해하기가 어려울 수 있으므로 여기에서 설명하고 있습니다.문제가 될 경우 필드 대신 메소드 또는 게터/세터를 사용하여 문제를 해결할 수 있습니다.

슈퍼:내부]

고급 정보

를 읽는 경우 튜토리얼의 첫 번째 시간 이 섹션에서는 건너뛸 수 있습니다.

상속 및super의 내부 메커니즘에 관한 것입니다.

super의 후드 아래에서 조금 더 깊이 들어가 봅시다. 우리는 길을 따라 흥미로운 것들을 보게 될 것입니다.,

먼저 말하자면,지금까지 배운 모든 것에서super가 전혀 작동하지 않는 것은 불가능합니다!

그래,사실,스스로에게 물어 보자,기술적으로 어떻게 작동해야합니까? 객체 메소드가 실행되면 현재 객체를this로 가져옵니다. 면 우리는 전화super.method()그리고 엔진을 필요로method에서의 프로토타입은 현재 개체입니다. 그러나 어떻게?작업이 단순 해 보일 수도 있지만 그렇지 않습니다., 엔진 알고 현재 개체this,그래서 그것을 얻을 수있는 부모methodthis.__proto__.method. 불행히도 이러한”순진한”솔루션은 작동하지 않습니다.문제를 설명하겠습니다. 클래스가 없으면 단순성을 위해 일반 객체를 사용합니다.

를 건너뛸 수 있습니다 이 부분과 아래로 이동하여]하위 섹션을 원하지 않는 경우 세부 사항을 알고. 그건 해를 끼치 지 않을거야. 또는 사물을 심층적으로 이해하는 데 관심이 있다면 읽어보십시오.

아래 예에서rabbit.__proto__ = animal., 지금 시도해보자:에서rabbit.eat()우리는 전화animal.eat(),사용하는this.__proto__:

라인에서(*)우리는 우리eat에서 프로토타입(animal)그리고 그것의 컨텍스트에서는 현재 개체입니다. 참고하는.call(this)중요하기 때문에,여기에 간단한this.__proto__.eat()가 실행하는 부모eat의 컨텍스트에서 프로토타입하지 않은 현재 개체입니다.,

그리고 위의 코드에서 실제로 의도 한대로 작동합니다:올바른alert가 있습니다.

이제 체인에 객체를 하나 더 추가하겠습니다. 우리는 일이 어떻게 깨지는 지 볼 것입니다:

코드가 더 이상 작동하지 않습니다! 우리는longEar.eat()를 호출하려고 오류를 볼 수 있습니다.

그렇게 명확하지 않을 수도 있지만longEar.eat()호출을 추적하면 그 이유를 알 수 있습니다. 에 모두 선(*)(**)값의this은 현재 개체(longEar)., 모든 객체 메소드는 프로토 타입이나 무언가가 아닌 현재 객체를this로 가져옵니다.

여기에 사진의 일어나는 무엇:

문제를 해결될 수 없을 사용하여this혼자입니다.

]

하는 솔루션을 제공,자바 스크립트를 추가 하나 더 특별한 내부 속성에 대한 기능:].,

함수가 클래스 또는 객체 메소드로 지정되면 해당]속성이 해당 객체가됩니다.

그런 다음super는이를 사용하여 상위 프로토 타입 및 해당 메소드를 해결합니다.

보이 어떻게 작동하는 최초,일반 객체:

방법은 없습니다”무료”

으로 우리가 알려지기 전에는,일반적으로 기능은”무료”,객체에 바인딩에서 JavaScript. 따라서 객체간에 복사하고 다른this로 호출 할 수 있습니다.,

]의 존재는 메소드가 객체를 기억하기 때문에 그 원칙을 위반합니다. ]는 변경할 수 없으므로이 본드는 영원합니다.

]가 사용되는 언어의 유일한 장소는super입니다. 따라서 메서드가super를 사용하지 않으면 여전히 무료로 간주하고 객체간에 복사 할 수 있습니다. 그러나super를 사용하면 상황이 잘못 될 수 있습니다.,

여기에서의 데모의 잘못된super결과 복사 후

전화tree.sayHi()보여줍니다”난 동물을”. 확실히 잘못되었습니다.

이유는 간단하다:

여기에 무슨 일이 일어 나는지의 다이어그램:

방법,기능하지 않은 속성

차이가 있을 수 있습 non-을 위해 필수적,우리 그러나 그것의 중요한 자바 스크립트.

아래의 예에서는 비 메소드 구문이 비교를 위해 사용됩니다., ]속성을 설정하지 않고 상속 작동하지 않는다:

요약

  1. 을 확장하는 클래스:class Child extends Parent:
    • 의미하는Child.prototype.__proto__될 것입니다Parent.prototype래 방법은 상속됩니다.
  2. 경우 재정의를 생성자:
    • 우리는 통화 부모가 생성자를super()에서는Child생성자를 사용하기 전에this.,
  3. 재정의하는 경우 다른 방법:
    • 사용할 수 있는super.method()에서는Child메소드를 호출하는Parent방법입니다.
  4. 내부:
    • 메소드는 내부]속성에서 클래스/객체를 기억합니다. 이것이super가 부모 메소드를 해결하는 방법입니다.
    • 따라서 한 객체에서 다른 객체로super가있는 메소드를 복사하는 것은 안전하지 않습니다.,

도:

  • 화살표수하지 않은 자신의this또는super,그래서 그들이 투명하게 맞으로 둘러싼 상황.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다