の継承-プロトタイプ
20970 ワード
原型は何ですか。
開発中に既存の機能を導入して拡張する必要がある場合があります.
ユーザーというオブジェクトがあり、人間に関するPropertyとメソッドがあるとします.ユーザーに相当しますが、少し異なるadminとguestオブジェクトを作成する必要があります.「ユーザーに機能を追加して、userメソッドをコピーまたは再実装することなくadminおよびguestオブジェクトを作成できますか?」このような考えが生まれます.
JavaScript言語の固有機能である「プロトタイプ継承」(prototype継承)を利用して、上記のアイデアを実現できます.
原型はどのように使いますか?
JavaScriptのオブジェクトには、リストに名前が付けられている[Prototype]の非表示プロファイルがあります.この非表示のプロパティの値はnullまたは他のオブジェクトを参照します.他のオブジェクトを参照する場合は、参照するオブジェクトを「プロトタイプ」と呼びます.
原型の動きには「神秘的」な面がある.なぜなら、objectからpropertyが読み込まれたが、propertyがない場合、JavaScriptは自動的にprototypeでpropertyを検索します.プログラミングでは、この操作方式を「プロトコルタイプ継承」と呼ぶ.言語レベルでサポートされる便利な機能や開発テクニックの多くは、プロトタイプ継承に基づいて生まれたものです.
[Prototype]Propertyは内部Propertyであり、Propertyを非表示にしますが、開発者はさまざまな方法で値を設定できます.
次の例に示すように、特殊な名前protoを使用して値を設定できます.
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal;
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // (*)
// 프로퍼티 eats과 jumps를 rabbit에서도 사용할 수 있게 되었습니다.
alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true
let animal = {
eats: true,
walk() {
alert("동물이 걷습니다.");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
// 메서드 walk는 rabbit의 프로토타입인 animal에서 상속받았습니다.
rabbit.walk(); // 동물이 걷습니다.
let user = {
name: "John",
surname: "Smith",
set fullName(value) {
[this.name, this.surname] = value.split(" ");
},
get fullName() {
return `${this.name} ${this.surname}`;
}
};
let admin = {
__proto__: user,
isAdmin: true
};
alert(admin.fullName); // John Smith (*)
// setter 함수가 실행됩니다!
admin.fullName = "Alice Cooper"; // (**)
alert(admin.fullName); // Alice Cooper , state of admin modified
alert(user.fullName); // John Smith , state of user protected
// admin.fullName = "Alice Cooper";, alert(admin.fullName);
// 위 두 문장처럼 같은 함수명이라고 할지라도 값을 할당하는지, 리턴하는지에 따라 set, get 함수가 결정됨
前更-[extends]
class Rabbit extends Animal {
hide() {
alert(`${this.name} 이/가 숨었습니다!`);
}
}
let rabbit = new Rabbit("흰 토끼");
rabbit.run(5); // 흰 토끼 은/는 속도 5로 달립니다.
rabbit.hide(); // 흰 토끼 이/가 숨었습니다!
開発中は、親メソッド全体を置き換えるのではなく、親メソッドに基づいていくつかの機能を変更し、親メソッドの機能を拡張したい場合があります.この場合、カスタムメソッドを作成しても、このプロシージャの前または後に親メソッドを呼び出すことができます.
キーワードsuperはこんな時に使います.
super.method(...)親クラスで定義されたメソッド、メソッドを呼び出します.
super(...)親ジェネレータを呼び出します.サブジェネレータ内でのみ使用できます.
この特徴を利用して、ウサギが止まると自動的に隠されるコードです.
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name}가 속도 ${this.speed}로 달립니다.`);
}
stop() {
this.speed = 0;
alert(`${this.name}가 멈췄습니다.`);
}
}
class Rabbit extends Animal {
hide() {
alert(`${this.name}가 숨었습니다!`);
}
stop() {
super.stop(); // 부모 클래스의 stop을 호출해 멈추고,
this.hide(); // 숨습니다.
}
}
let rabbit = new Rabbit("흰 토끼");
rabbit.run(5); // 흰 토끼가 속도 5로 달립니다.
rabbit.stop(); // 흰 토끼가 멈췄습니다. 흰 토끼가 숨었습니다!
継承クラスの作成者にはsuper(...)を使用する必要があります.呼び出しが必要、super(...)呼び出さないとエラーが発生します.super(...)thisを使用する前に、呼び出す必要があります.
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
// ...
}
class Rabbit extends Animal {
constructor(name, earLength) {
super(name); // 부모 클래스의 생성자 속 name을 사용하기 위함.
this.earLength = earLength;
}
// ...
}
// 이제 에러 없이 동작합니다.
let rabbit = new Rabbit("흰 토끼", 10);
alert(rabbit.name); // 흰 토끼
alert(rabbit.earLength); // 10
コメントサイト
Reference
この問題について(の継承-プロトタイプ), 我々は、より多くの情報をここで見つけました https://velog.io/@uvula6921/JavaScript의-상속-prototypeテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol