第25章類
44114 ワード
クラスの導入
ES6
にクラスが導入される前に、ES5
においてコンストラクタおよびプロトタイプによって継承が達成され得る.コンストラクション関数とクラスにはいくつかの違いがあります.
演算子を使用せずに
new
およびnew
キーワードを提供する.extends
です.クラスは、コンストラクション関数に基づくオブジェクトの作成方法よりも堅牢で明瞭です.
クラス反発
クラスは関数で測定されます.
クラス宣言として定義されたクラスは、関数宣言のクラスと同様に、実行時の前に評価を行い、関数オブジェクトを生成します.
const Person = '';
{
// 호이스팅이 발생하지 않는다면 ''이 출력되야 한다.
console.log(Person); // // ReferenceError: Cannot access 'Person' before initialization
class Person {}
}
クラスはクラス定義の前に参照できません.console.log(Person); // ReferenceError: Cannot access 'Person' before initialization
class Person {}
インスタンス%
定義方法
class Person {
constructor(name) {
// 인스턴스 프로퍼티
this.name = name;
}
}
const me = new Person('Lee');
console.log(me); // Person {name: "Lee"}
インスタンス見積書は、super
の内部でstrict mode
に見積書を追加する必要があります.では、クラスの体に職業資格を宣言したらどうなるのでしょうか.
class Person {
// 인스턴스 프로퍼티 정의
name = 'Lee'
}
const me = new Person();
console.log(me); // Person {name: "Lee"}
クラスマスターはメソッドのみを宣言できます.クラス・ボディで前述したようにインスタンス・プロシージャを宣言すると、構文エラーが発生します.ただし、上記の例は最新のブラウザまたはノードです.jsで実行すると、構文エラーは発生せず、正常に動作します.
🔎 推奨定義クラスフィールド
上記の定義はクラスフィールド定義と呼ばれ、クラスフィールドはクラスベースのオブジェクト向け言語でクラスが生成するインスタンスのpropertyを指す.
JAvascriptも2021年1月にインスタンスプロセスをクラスフィールドとして定義することを提案した.これまでECMAScriptの標準にアップグレードされていませんが、標準仕様にアップグレードされているため、最新のブラウザと最新のノードです.jsは予めこの方式を実現している.
最新のブラウザはChrome 72以降、最新のNodeです.jsはバージョン12以上を表す.
🚸 クラスフィールドの定義方法に関する注意事項
class Person {
this.name = ''; // SyntaxError: Unexpected token '.'
}
constructor
に番組をバインドしてはならない.this
はクラスのthis
およびメソッド内でのみ有効である.class Person {
name;
}
const me = new Person();
console.log(me); // Person {name: undefined}
初期値が割り当てられていない場合は、定義されていない値があります.class Person {
name;
constructor(name) {
this.name = name; // 초기화
}
}
const me = new Person('Lee');
console.log(me); // Person {name: "Lee"}
外部初期値に初期化する必要がある場合は、this
で初期化する必要があります.class Person {
constructor(name) {
this.name = name;
}
}
const me = new Person('Lee');
console.log(me); // Person {name: "Lee"}
実際には、インスタンスプロセスを初期化する必要がある場合、constructor
の外で定義する必要はありません.いずれにしても、constructor
の内部には、対応するプログラムを参照して初期値が割り当てられるからである.私有財産
クラスは、
constructor
、constructor
、private
、public
などのアクセス制限子をサポートしません.ただし、最新のブラウザとノードを含むprotected
のプロパティを定義できる仕様があります.jsはすでに実現した.private
位のうち、上位はprivate
だった.#
参照、private
も添付します.class Person {
// private 프로퍼티 정의
#name = '';
constructor(name) {
// private 프로퍼티 참조
this.#name = name;
}
// getter 함수
get name() {
return this.#name;
}
}
const me = new Person('Lee');
console.log(me.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class
console.log(me.name); // 'Lee'
#
のパーセントprivate
はクラス外では参照できません.#name
関数で間接的にアクセスする必要があります.class Person {
constructor(name) {
this.#name = name;
// SyntaxError: Private field '#name' must be declared in an enclosing class
}
}
さらに、getter
パーセントはクラスで定義する必要があります.private
で直接定義するとエラーが発生します.静的構成
クラスは
constructor
キーワードを使用して静的メソッドを定義できますが、静的propertyは定義できません.しかし、最新のブラウザやNodeも含めて、現在も推奨されています.jsはすでに実現した.class MyMath {
// static public 프로퍼티 정의
static PI = 22 / 7;
// static pirvate 프로퍼티 정의
static #num = 10;
// static 메서드
static increment() {
return ++MyMath.#num;
}
}
console.log(MyMath.PI); // 3.142857142857143
console.log(MyMath.increment()); // 11
拡張クラス
プロトコル・タイプ・ベースの継承は、プロトコル・タイプ・チェーンを介して他のオブジェクトの資産を継承する概念ですが、継承ベースのクラス拡張は、既存のクラスを継承することによって新しいクラスを拡張することによって定義されます.
class Animal {
constructor(age, weight) {
this.age = age;
this.weight = weight;
}
eat() { return 'eat'; }
move() { return 'move'; }
}
class Bird extends Animal {
fly() { return 'fly'; }
}
const bird = new Bird(1, 5);
console.log(bird); // Bird {age: 1, weight: 5}
console.log(bird instanceof Bird); // true
console.log(bird instanceof Animal); // true
console.log(bird.eat()); // eat
console.log(bird.move()); // move
console.log(bird.fly()); // fly
static
キーワードを使用したクラス拡張は、単純で直感的です.拡張を継承するクラスをサブクラス(subclass)と呼び、サブクラスに継承するクラスをスーパークラス(super-class)と呼ぶ.ダイナミック継承
extends
キーワードは、クラスを継承するだけでなく、構造関数を継承してクラスを拡張することもできます.ただし、extends
キーワードの前にクラスが必要です.function Base(a) {
this.a = a;
}
class Derived extends Base {}
const derived = new Derived(1);
console.log(derived); // Derived {a: 1}
条件に基づいて継承オブジェクトを動的に決定することもできます.function Base1() {}
class Base2 {}
let condition = true;
class Derived extends (condition ? Base1 : Base2) {}
const derived = new Derived();
console.log(derived); // Derived {}
console.log(derived instanceof Base1); // true
console.log(derived instanceof Base2); // false
スーパーキー
extends
キーワードは、関数のように呼び出されてもよいし、識別子のように参照されてもよい.1.スーパーコール
呼び出し
super
は、スーパークラスのsuper
を呼び出す.class Base {
constructor(a, b) {
this.a = a;
this.b = b;
}
}
class Derived extends Base {
constructor(a, b, c) {
super(a, b);
this.c = c;
}
}
const derived = new Derived(1, 2, 3);
console.log(derived); // Derived {a: 1, b: 2, c:3}
因数1,2,3はconstructor
クラスのDerived
に渡され、constructor
を呼び出すことによってsuper
クラスのBase
に部分的に渡される.constructor
を呼び出すときの注意点はいくつかあります.💡 サブクラスに
super
が省略されていない場合はsuperを呼び出す必要があります.class Base { ... }
class Derived extends Base {
constructor() {
// ReferenceError
console.log('constructor call');
}
}
const derived = new Derived();
💡 サブクラスのconstructor
からconstructor
を呼び出すまで、super
は参照できません.class Base { ... }
class Derived extends Base {
constructor() {
// ReferenceError
this.a = 1;
super();
}
}
const derived = new Derived(1);
💡 this
は、サブクラスのsuper
で呼び出さなければならない.class Base {
constructor() {
super(); // SyntaxError: 'super' keyword unexpected here
}
}
function Foo() {
super(); // SyntaxError: 'super' keyword unexpected here
}
2.スーパーリファレンス
メソッド内では、
constructor
を参照してスーパークラスメソッドを呼び出すことができる.class Base {
constructor(name) {
this.name = name;
}
sayHi(){
return `Hi! ${this.name}`;
}
}
class Derived extends Base {
sayHi() {
return `${super.sayHi()}. how are you doing?`;
}
}
const derived = new Derived('Lee');
console.log(derived.sayHi()); // Hi! Lee. how are you doing?
サブクラスのプロトタイプ方法では、super
はスーパークラスのプロトタイプ方法super.sayHi
を指す.継承クラスのインスタンス作成プロセス
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
class ColorRectangle extends Rectangle {
constructor(width, height, color) {
super(width, height);
this.color = color;
}
}
const colorRectangle = new ColorRectangle(2, 4, 'red');
console.log(colorRectangle); // ColorRectangle {width: 2, height: 4, color: 'red'}
📚 1.サブクラスのスーパーコール
呼び出し
sayHi
は、サブクラスのコンストラクション関数で完了する必要があります.サブクラスは自分でインスタンスを作成するのではなく、スーパークラスにインスタンスの作成を委任するためです.サブクラスが新しい演算子とともに呼び出されると、サブクラスcounterchitor内部の
super
キーワードが関数のように呼び出され、スーパークラスのコンストラクション関数が呼び出されます.📚 2.スーパークラスインスタンスを作成し、そのインスタンスをバインドする
// 수퍼클래스
class Rectangle {
constructor(width, height) {
console.log(this); // ColorRectangle {}
...
インスタンスはスーパークラスによって作成されますが、new演算子とともに呼び出されるクラスがサブクラスであることが重要です.super
とは、new演算子とともに呼び出される関数のサブクラスを指す.したがって、インスタンスはサブクラスによって作成されたものとみなされます.📚 3.スーパークラスインスタンスの初期化
class Rectangle {
constructor(width, height) {
console.log(this); // ColorRectangle {}
this.width = width;
this.height = height;
console.log(this); // ColorRectangle {width: 2, height: 4}
}
...
スーパークラスのconstructorが実行され、this
にバインドされたインスタンスを初期化します.📚 4.サブクラス構築関数を返してバインド
class ColorRectangle extends Rectangle {
constructor(width, height, color) {
super(width, height);
console.log(this); // ColorRectangle {width: 2, height: 4}
...
呼び出しthis
は終了し、サブクラス構築関数はsuper
が返すインスタンスをsuper
にバインドする.サブクラスは、個別のインスタンスを作成するのではなく、this
から返されたインスタンスをsuper
にバインドして使用を続行します.📚 5.サブクラスのインスタンスの初期化と戻し
this
にバインドされたインスタンスにpropertyを追加し、パラメータ伝達の初期値としてコンストラクション関数を使用してインスタンスのpropertyを初期化します.クラスのすべての処理が完了すると、バインド完了インスタンスの
this
がデフォルトで返されます.class ColorRectangle extends Rectangle {
constructor(width, height, color) {
super(width, height);
console.log(this); // ColorRectangle {width: 2, height: 4}
this.color = color;
console.log(this); // ColorRectangle {width: 2, height: 4, color: 'red'}
}
}
const colorRectangle = new ColorRectangle(2, 4, 'red');
Reference
この問題について(第25章類), 我々は、より多くの情報をここで見つけました https://velog.io/@niyu/25장-클래스テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol