ホームページ > 記事 > ウェブフロントエンド > JavaScript はどのように継承を実装するのでしょうか? js の 6 つの一般的な継承メソッド
JavaScript で継承を実装するにはどうすればよいですか?この記事では、js の一般的な継承メソッドを 6 つ紹介します。困っている友人は参考にしていただければ幸いです。
オブジェクト指向プログラミングの非常に重要な側面は、オブジェクトの継承です。 B オブジェクトを継承することにより、A オブジェクトは B オブジェクトのすべてのプロパティとメソッドを直接所有できます。これはコードを再利用する場合に非常に役立ちます。
ほとんどのオブジェクト指向プログラミング言語は、「クラス」を通じてオブジェクトの継承を実装します。従来、JavaScript 言語の継承はクラス (ES6 ではクラス構文が導入されました) を通じてではなく、「プロトタイプ オブジェクト」を通じて実装されていました。では、JS の一般的な継承メソッドにはどのようなものがあるのでしょうか?
この記事のソース コードが必要な場合は、Six Common Inheritance Methods
この記事が役立つと思われる場合は、クリックしてください。 GitHub ブログに投稿してください。「いいね!」と「フォロー」していただき、ありがとうございます。
このメソッドの重要な点は次のとおりです。サブタイプのプロトタイプは、親タイプのインスタンス オブジェクトです。
//父类型 function Person(name, age) { this.name = name, this.age = age, this.play = [1, 2, 3] this.setName = function () { } } Person.prototype.setAge = function () { } //子类型 function Student(price) { this.price = price this.setScore = function () { } } Student.prototype = new Person() // 子类型的原型为父类型的一个实例对象 var s1 = new Student(15000) var s2 = new Student(14000) console.log(s1,s2)
しかし、このメソッドの本質は、サブクラスのプロトタイプが親クラスのインスタンスを指すことです。 サブクラスのインスタンスは、__proto__ を介して Person のインスタンスである Student.prototype にアクセスできるため、親クラスのプライベート メソッドにアクセスし、__proto__ メソッドを介して親クラスのプロトタイプを指すことができます。親クラスのプロトタイプの 。したがって、親クラスのプライベートおよびパブリック メソッドとプロパティは、サブクラスのパブリック プロパティとして扱われます。
サブクラスは、親クラスのプライベート プロパティとパブリック メソッドを扱うことによって、親クラスのプロパティとメソッドを継承します。親クラスを独自のパブリック プロパティおよびメソッドとして使用する。基本的なデータ型を操作する場合は値を操作し、参照データ型を操作する場合はアドレスを操作することは誰もが知っています。親クラスのプライベート プロパティは、サブクラスによって継承されるときにパブリック属性として使用されるため、サブクラス 1 がこの属性を操作すると、サブクラス 2 に影響します。
s1.play.push(4) console.log(s1.play, s2.play) console.log(s1.__proto__ === s2.__proto__)//true console.log(s1.__proto__.__proto__ === s2.__proto__.__proto__)//true
s1 の再生属性が変化し、同時に s2 の再生属性もそれに応じて変化します。
もう 1 つ注意すべき点は、新しいメソッドをサブクラスに追加するか、親クラスのメソッドをオーバーライドする必要がある場合は、プロトタイプを置き換えるステートメントの後に忘れずにメソッドを配置することです
function Person(name, age) { this.name = name, this.age = age } Person.prototype.setAge = function () { console.log("111") } function Student(price) { this.price = price this.setScore = function () { } } // Student.prototype.sayHello = function () { }//在这里写子类的原型方法和属性是无效的, //因为会改变原型的指向,所以应该放到重新指定之后 Student.prototype = new Person() Student.prototype.sayHello = function () { } var s1 = new Student(15000) console.log(s1)
#機能:
:
の後に実行する必要があり、コンストラクターに配置することはできません
<script> function Person(name, age) { this.name = name, this.age = age, this.setName = function () {} } Person.prototype.setAge = function () {} function Student(name, age, price) { Person.call(this, name, age) // 相当于: this.Person(name, age) /*this.name = name this.age = age*/ this.price = price } var s1 = new Student('Tom', 20, 15000)</script>
このメソッドは部分的な継承のみを実装します。親クラスのプロトタイプにもメソッドと属性がある場合、サブクラスはこれらのメソッドと属性を取得できません。
console.log(s1.setAge())//Uncaught TypeError: s1.setAge is not a function
特長
:プロトタイプチェーン継承で親クラスの参照属性を共有するサブクラスインスタンスの問題を解決します
#サブクラス インスタンスを作成するときに、親クラスにパラメータを渡すことができます
多重継承を実装できます (複数の親クラス オブジェクトを呼び出す)
##欠点
:インスタンスは親クラスのインスタンスではなく、サブクラスのインスタンスです
这种方式融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。不过也存在缺点就是无论在什么情况下,都会调用两次构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数的内部,子类型最终会包含父类型对象的全部实例属性,但我们不得不在调用子类构造函数时重写这些属性。 优点: 可以继承实例属性/方法,也可以继承原型属性/方法 不存在引用属性共享问题 可传参 函数可复用 缺点: 调用了两次父类构造函数,生成了两份实例 这种方式通过父类原型和子类原型指向同一对象,子类可以继承到父类的公有方法当做自己的公有方法,而且不会初始化两次实例方法/属性,避免的组合继承的缺点。 但这种方式没办法辨别是对象是子类还是父类实例化 优点: 不会初始化两次实例方法/属性,避免的组合继承的缺点 缺点: 没办法辨别是实例是子类还是父类创造的,子类和父类的构造函数指向是同一个。 借助原型可以基于已有的对象来创建对象, 同样的,Student继承了所有的Person原型对象的属性和方法。目前来说,最完美的继承方法! ES6中引入了class关键字,class可以通过extends关键字实现继承,还可以通过static关键字定义类的静态方法,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。 ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。 需要注意的是,class关键字只是原型的语法糖,JavaScript继承仍然是基于原型实现的。 优点: 语法简单易懂,操作更方便 缺点: 并不是所有的浏览器都支持class关键字 总结:以上就是本篇文的全部内容,代码很简单,大家可以动手试试。希望能对大家的学习有所帮助,更多相关教程请访问JavaScript视频教程,jQuery视频教程,bootstrap教程!
方式四: 组合继承优化1
function Person(name, age) {
this.name = name,
this.age = age,
this.setAge = function () { }
}
Person.prototype.setAge = function () {
console.log("111")
}
function Student(name, age, price) {
Person.call(this, name, age)
this.price = price
this.setScore = function () { }
}
Student.prototype = Person.prototype
Student.prototype.sayHello = function () { }
var s1 = new Student('Tom', 20, 15000)
console.log(s1)
console.log(s1 instanceof Student, s1 instanceof Person)//true true
console.log(s1.constructor)//Person
方式五: 组合继承优化2
var B = Object.create(A)
以A对象为原型,生成了B对象。B继承了A的所有属性和方法。 function Person(name, age) {
this.name = name,
this.age = age
}
Person.prototype.setAge = function () {
console.log("111")
}
function Student(name, age, price) {
Person.call(this, name, age)
this.price = price
this.setScore = function () {}
}
Student.prototype = Object.create(Person.prototype)//核心代码
Student.prototype.constructor = Student//核心代码
var s1 = new Student('Tom', 20, 15000)
console.log(s1 instanceof Student, s1 instanceof Person) // true true
console.log(s1.constructor) //Student
console.log(s1)
方式六:ES6中class 的继承
class Person {
//调用类的构造方法
constructor(name, age) {
this.name = name
this.age = age
}
//定义一般的方法
showName() {
console.log("调用父类的方法")
console.log(this.name, this.age);
}
}
let p1 = new Person('kobe', 39)
console.log(p1)
//定义一个子类
class Student extends Person {
constructor(name, age, salary) {
super(name, age)//通过super调用父类的构造方法
this.salary = salary
}
showName() {//在子类自身定义方法
console.log("调用子类的方法")
console.log(this.name, this.age, this.salary);
}
}
let s1 = new Student('wade', 38, 1000000000)
console.log(s1)
s1.showName()
以上がJavaScript はどのように継承を実装するのでしょうか? js の 6 つの一般的な継承メソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。