這是我見到的幾種js繼承方法,如果有文章中沒有提及的,希望可以分享共同學習
(一)原型鏈繼承
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
console.log("parent name is " + this.name)
}
function Child(name) {
this.name = name
}
Child.prototype = new Parent('張三')
Child.prototype.constructor = Child
Child.prototype.getName = function() {
console.log('child name is ' + this.name)
}
var child = new Child('小張')
child.getName() // child name is 小張
只要是原型鏈中出現過的原型,都可以說是該原型鏈派生的實例的原型。
這種方法有個缺點:
- 子類型無法給超類型傳遞參數,在面向對象的繼承中,我們總希望通過 var child = new Child('son', 'father'); 讓子類去調用父類的構造器來完成繼承。
(二) 類是繼承
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
console.log("parent name is " + this.name)
}
Parent.prototype.do = function() {
console.log("doSomething")
}
function Child(name, parentName) {
Parent.call(this, parentName)
this.name = name
}
Child.prototype.getName = function() {
console.log('child name is ' + this.name)
}
var child = new Child('小張')
child.getName() // child name is 小張
child.do() // child.do is not a functio
相當于 Parent 這個函數在 Child 函數中執行了一遍,并且將所有與 this 綁定的變量都切換到了 Child 上,這樣就克服了第一種方式帶來的問題。
缺點:
1. Parent函數在Child中執行一遍, 并且不能復用一些共有的函數
(三)組合式繼承, 一二兩種方法的結合
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
console.log("parent name is " + this.name)
}
Parent.prototype.do = function() {
console.log("doSomething")
}
function Child(name, parentName) {
Parent.call(this, parentName)
this.name = name
}
Child.prototype.getName = function() {
console.log('child name is ' + this.name)
}
Child.prototype = new Parent();
Child.prototype.construtor = Child;
var child = new Child('小張')
child.getName() // child name is 小張
child.do() // doSomething
缺點:
Parent 需要調用兩次
(四)寄生組合式繼承
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
console.log("parent name is " + this.name)
}
Parent.prototype.do = function() {
console.log("doSomething")
}
function Child(name, parentName) {
Parent.call(this, parentName)
this.name = name
}
function initPrototype(Parent, Child) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.construtor = Child;
}
initPrototype(Parent, Child);
Child.prototype.getName = function() {
console.log('child name is ' + this.name)
}
var child = new Child('小張', '張三')
child.getName() // child name is 小張
child.do() // doSomething
(五)ES6繼承
class Parent {
constructor(name) {
this.name = name;
}
do() {
console.log('something');
}
getName() {
console.log('parent name is', this.name);
}
}
class Child extends Parent {
constructor(name, parentName) {
super(parentName);
this.name = name;
}
getName() {
console.log('child name is', this.name);
}
}
const child = new Child('小張', '張三');
child.getName(); // child name is 小張
child.do(); // something