1. なぜ継承が必要なのでしょうか?
まずコードの一部を見てみましょう。
function Person(name, age) {
this.name = name
this.age = age
this.money = function () {
console.log('赚钱')
}
}
var zs = new Person()
var ls = new Person()
console.log(zs.name === ls.name) //true
console.log(zs.money === ls.money) //false
インスタンス オブジェクトはコンストラクターを通じて作成されます。Person は zs および ls インスタンス オブジェクトのコンストラクターです。すべての Person オブジェクトには、同様の機能を持つ Money メソッドがあります。zs と ls の 2 つのインスタンスがコンストラクターのメソッドにアクセスすると、各インスタンス オブジェクトは、このメソッドを格納するためにメモリ内に別個の領域を開きます。これらは異なるメモリ空間を占有するため、メモリの浪費の問題が発生します。
したがって、継承を使用する必要があります。
継承は、あるオブジェクトが別のオブジェクトのプロパティやメソッドにアクセスできるようにする方法です。
2. JavaScript での継承:
① プロトタイプチェーンの継承:
サブタイプのプロトタイプは、スーパータイプのインスタンス オブジェクトです。親コンストラクターをインスタンス化し、サブクラスのプロトタイプが親クラスのインスタンスを指すようにすると、サブクラスは親クラスのプロトタイプ オブジェクトのプライベート プロパティとパブリック メソッドを呼び出すことができます。
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.money = function () {
console.log('赚钱')
}
function Student(name, age) {
Person.call(this, name, age)
}
Student.prototype = new Person()
// Student的原型对象指向Person的实例对象就可以访问Person里面的原型对象,Person的原型对象上有money的方法就可以访问
Student.prototype.study = function () {
console.log('学习')
}
var zs = new Student('zs', 18)
console.log(zs)
親コンストラクター Person がインスタンス化されて、親コンストラクターのインスタンス オブジェクトが作成されます。親コンストラクターのインスタンス オブジェクトと親コンストラクターのプロトタイプ オブジェクトは 2 つの異なるメモリ アドレスにあり、2 つの異なるオブジェクトです。
Student.prototype = new Person() を通じて、インスタンス化されたオブジェクトはサブコンストラクターのプロトタイプ オブジェクト Student.prototype に割り当てられます。これは Student.prototype に Person のインスタンス オブジェクトを指すようにするのと同じです。パーソンのインスタンス オブジェクト、パーソンのプロトタイプ オブジェクトには、インスタンス オブジェクト.__proto__ を通じてアクセスできます。パーソンのプロトタイプオブジェクトには「money」メソッドがあり、インスタンスオブジェクトはこのメソッドを利用することができます。Student プロトタイプ オブジェクトは Person のインスタンス オブジェクトを指すため、Student コンストラクターは「お金を稼ぐ」メソッドを使用して継承を実現できます。
親クラスが新しいプロトタイプ メソッドまたはプロトタイプ プロパティを追加すると、サブクラスはそれにアクセスできるようになります。サブクラスに新しいプロパティやメソッドを追加する場合は、Student.prototype = new Person() を記述した後に実行する必要があります。
② 親コンストラクターを使用して継承します。
親コンストラクターを呼び出し、子コンストラクターを指すように親コンストラクター内でこれを変更します。
// 利用父构造函数继承属性并且添加属性
function Person(name, age) {
this.name = name
this.age = age
}
function Student(name, age, sex) {
// 继承Person的属性
// 用call方法改变this指向,让Person里的this指向Student
Person.call(this, name, age)
// 添加sex属性
this.sex = sex
}
var student = new Student('zs', 18, '男')
console.log(student)
親コンストラクター Person の this は親コンストラクターのオブジェクト インスタンスを指し、子コンストラクター Student の this は子コンストラクターのオブジェクト インスタンスを指します。
子コンストラクターは、Person.call(this) を通じて親コンストラクター Person を呼び出し、親コンストラクターのオブジェクト インスタンスの this を、子コンストラクターのオブジェクト インスタンスを指すように変更します。この時点で、子コンストラクター Student は親コンストラクター Person のプロパティを使用して継承を実装できます。
③クラス継承
ES6 では、クラスは class キーワードを通じて定義され、サブクラスは extends を通じて親クラスを継承できます。
// Person类
class Person {
constructor(name, age, gender) {
this.name = name
this.age = age
this.gender = gender
}
learn() {
console.log('学习')
}
}
var zs = new Person()
console.log(zs)
//es6 student继承Person类 extends
class Student extends Person {
constructor(name, age, gender) {
super(name, age, gender)
}
}
var student = new Student()
console.log(student)