es6에서는 클래스 및 확장 키워드를 사용하여 상속을 구현합니다. class 키워드는 클래스를 선언하기 위해 ES6에서 도입되었으며, 클래스(class)는 extends 키워드를 통해 상속될 수 있어 하위 클래스가 상위 클래스의 속성과 메서드를 상속받을 수 있도록 구문은 "클래스 상위 클래스 이름 {.. .} 클래스 하위 클래스 이름은 상위 클래스 이름 {...};"을 확장합니다.
이 튜토리얼의 운영 환경: Windows 7 시스템, ECMAScript 버전 6, Dell G3 컴퓨터.
es6에서는 클래스 키워드와 확장 키워드를 사용하여 상속을 구현할 수 있습니다.
1. 소개
클래스는 확장 키워드를 통해 상속을 달성할 수 있으므로 하위 클래스가 상위 클래스의 속성과 메서드를 상속받을 수 있습니다. 이는 프로토타입 체인을 수정하여 ES5의 상속을 구현하는 것보다 훨씬 더 명확하고 편리합니다.
//父类 class Point { ... } //子类 class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return this.color + '' + super.toString(); // 调用父类的toString方法 } }
위 코드에서 super 키워드는 생성자 메소드와 toString 메소드 모두에 나타납니다. 여기서 Super는 상위 클래스의 생성자를 나타내며 상위 클래스의 새 인스턴스 객체를 생성하는 데 사용됩니다.
ES6에서는 하위 클래스가 생성자 메서드에서 super()를 호출해야 한다고 규정합니다. 그렇지 않으면 오류가 보고됩니다. 이는 상위 클래스와 동일한 인스턴스 속성을 얻으려면 하위 클래스의 자체 this 객체를 먼저 상위 클래스의 생성자를 통해 형성해야 하기 때문입니다. . 및 메서드를 추가한 다음 하위 클래스의 자체 인스턴스 속성과 메서드를 추가합니다.
이것은 ES5의 상속 메커니즘에서 독립 하위 클래스의 인스턴스 객체가 먼저 생성된 다음 상위 클래스의 메서드가 이 객체에 추가되기 때문입니다. 즉, "인스턴스 우선, 상속 마지막"입니다. 상속 메커니즘은 먼저 상위 클래스의 속성과 메소드를 빈 객체에 추가한 다음 해당 객체를 하위 클래스의 인스턴스로 사용하는 것, 즉 "상속 우선, 인스턴스 마지막"입니다.
이는 새 하위 클래스 인스턴스가 생성될 때마다 상위 클래스의 생성자가 한 번씩 실행되어야 한다는 의미입니다.
class Foo { constructor() { console.log(1); } } class Bar extends Foo { constructor() { super(); console.log(2); } } const bar = new Bar(); // 1 2
위 코드에서 하위 클래스 Bar가 새 인스턴스를 생성하면 1과 2가 출력됩니다. 인수 클래스 구성 함수가 super()를 호출하면 상위 클래스 생성자가 한 번 실행됩니다. 이 키워드는 하위 클래스의 생성자에서 super를 호출한 후에만 사용할 수 있습니다. 그렇지 않으면 오류가 보고됩니다. 이는 하위 클래스 인스턴스의 생성이 먼저 상위 클래스의 상속을 완료해야 하기 때문입니다. 오직 슈퍼 메소드만이 하위 클래스 인스턴스가 상위 클래스를 상속하도록 허용할 수 있습니다.
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y, color) { this.color = color; super(x, y); this.color = color; } }"
하위 클래스가 생성자 메서드를 정의하지 않으면 이 메서드가 기본적으로 추가되며 그 안에서 super가 호출됩니다. 즉, 명시적으로 정의되었는지 여부에 관계없이 모든 하위 클래스에는 생성자 메서드가 있습니다. .
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { } let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8} class ColorPoint extends Point { constructor(...args) { super(...args); } } let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8}
2. 속성 및 비공개 메소드의 비공개 상속
비공개 속성 및 메소드를 제외하고 상위 클래스의 모든 속성과 메소드는 하위 클래스에 상속됩니다. 하위 클래스는 상위 클래스의 전용 속성을 상속할 수 없습니다. 또는 전용 속성은 자신이 정의된 클래스에서만 사용할 수 있습니다.
class Foo { #p = 1; #m() { console.log('hello'); } } class Bar extends Foo { constructor() { super(); console.log(this.#p); // 报错 this.#m(); // 报错 } }
위의 예에서 하위 클래스 Bar가 상위 클래스 Foo의 전용 속성이나 전용 메서드를 호출하면 오류가 보고됩니다.
부모 클래스가 전용 속성에 대한 읽기 및 쓰기 메서드를 정의하는 경우 하위 클래스는 이러한 메서드를 통해 전용 속성을 읽고 쓸 수 있습니다.
class Foo { #p = 1; getP() { return this.#p; } } class Bar extends Foo { constructor() { super(); console.log(this.getP()); // 1 } }
3. 정적 속성 및 메서드 상속
상위 클래스의 정적 속성 및 정적 메서드도 하위 클래스에서 상속됩니다.
class A { static hello() { console.log('hello world'); } } class B extends A { } B.hello() // hello world
위 코드에서 hello()
는 A
클래스의 정적 메서드이고 B
는 A
를 상속합니다. >, A
의 정적 메서드도 상속합니다. hello()
是A
类的静态方法,B
继承A
,也继承了A
的静态方法。
注意,静态属性是通过浅拷贝实现继承的,如果继承的属性是原始数据类型,子类中操作继承的静态属性不会影响到父类,但如果继承的属性是一个对象,那么子类修改这个属性会印象到父类
class C { static foo = 100; } class D extends C { constructor() { super(); D.foo--; } } const d = new D(); C.foo; // 100 D.foo; // 99 class A { static foo = { n: 100 }; } class B extends A { constructor() { super(); B.foo.n--; } } const b = new B(); B.foo.n // 99 A.foo.n // 99
4.Object.getPrototypeOf()
Object.getPrototypeOf()
class Point { /*...*/ } class ColorPoint extends Point { /*...*/ } Object.getPrototypeOf(ColorPoint) === Point // true
4.Object.getPrototypeOf()
Object.getPrototypeOf()
메소드를 사용하여 하위 클래스에서 상위 클래스를 가져올 수 있습니다. class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); } } new A(); // A new B(); // B따라서 이 방법을 사용하여 클래스가 다른 클래스를 상속하는지 여부를 확인할 수 있습니다. 5. super 키워드 super 키워드는 함수 또는 객체로 사용될 수 있습니다. 첫 번째 경우, super가 함수로 호출되면 상위 클래스의 생성자를 나타냅니다. super를 호출하는 기능은 하위 클래스의 this 객체를 형성하고 부모 클래스의 인스턴스 속성과 메서드를 이 객체에 배치하는 것입니다.
class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 } } let b = new B();두 번째 경우, super가 객체로 사용될 때 일반 메소드에서는 상위 클래스의 프로토타입 객체를 가리키고 정적 메소드에서는 상위 클래스를 가리킵니다. 🎜
class A { constructor() { this.p = 2; } } class B extends A { get m() { return spuer.p; } } let b = new B(); b.m // undefined🎜위 코드에서 서브클래스 B의 super.p()는 super를 객체로 사용합니다. 이때 일반 객체의 super는 A.prototype을 가리키고, super.p()는 A.prototype과 동일합니다. .피(). 🎜🎜super는 상위 클래스의 프로토타입 객체를 가리키므로 상위 클래스 인스턴스에 정의된 메서드나 속성은 super를 통해 호출할 수 없습니다. 아래와 같이 🎜
class A {}; A.prototype.x = 2; class B extends A { constructor() { super(); console.log(super.x); } } let b = new B();🎜이 문제를 해결하려면 상위 클래스의 프로토타입 객체에 속성을 정의하면 됩니다.🎜
class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } m() { super.print(); } } let b = new B(); b.m(); // 2🎜ES6에서는 하위 클래스의 일반적인 메소드에서 super를 통해 상위 클래스의 메소드를 호출할 때 다음과 같이 규정하고 있습니다. , 메서드 내부의 this는 현재 하위 클래스 인스턴스를 가리킵니다🎜
class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } m() { super.print(); } } let b = new B(); b.m(); // 2
上面代码中,super.print()调用的是A.prototype.print(),但是此时方法内部的this指向是子类B的实例,所以输出2。
由于this指向的是子类实例,所有如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性
class A { constructor() { this.x = 1; } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; console.log(super.x); //undefind console.log(this.x); // 3 } }
上面代码中,super.x
赋值为3
,这时等同于对this.x
赋值为3
。而当读取super.x
的时候,读的是A.prototype.x
,所以返回undefined
。
如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。
class Parent { static myMethod(msg) { console.log('static', msg); } myMethod(msg) { console.log('instance', msg); } } class Children extends Parent { static myMethod(msg) { super.myMthod(msg); } myMethod(msg) { super.myMethod(msg); } } Child.myMethod(1); // static 1 var child = new Child(); child.myMethod(2); // instance 2
上面代码中,super
在静态方法之中指向父类,在普通方法之中指向父类的原型对象。
另外,在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例
class A { constructor() { this.x = 1; } static print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } static m() { super.print(); } } B.x = 3; B.m() // 3
在静态方法m中,super.print指向父类的静态方法,到那时this指向的是类B,而不是B的实例。
【推荐学习:javascript高级教程】
위 내용은 es6에서 상속을 구현하는 데 사용되는 것의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!