这是我见到的几种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