javascript中继承的几种实现方法
Contents
继承
在javacript继承很是重要,通过继承可以实现代码的复用,让子类继承父类从而减少代码量,记下来使用多个方法来实现继承.
1.原型链的继承
原型链继承存在的问题:
- 原型中包含的引用类型属性将被所有实例共享,某一个实例改变属性其他的实例属性也会跟着改变
- 子类在实例化的时候不能给父类构造函数传参
function Animal() {
this.color = ['yellow', 'black'];
}
Animal.prototype.getColor = function () {
console.log(this.color)
}
function Dog() { }
Dog.prototype = new Animal();
let dog = new Dog();
dog.getColor(); // ["yellow","black"]
dog.color.push('white');
let dog2 = new Dog();
dog2.getColor(); // ["yellow","black","white"]
2.借用构造函数实现继承
借用构造函数继承解决了原型链继承的2个问题:引用类型共享问题以及传参问题。但是由于方法定义在构造函数中,所以会导致创建子类实例都会创建一遍方法
function Animal(name) {
this.name = name;
this.getName = function () {
console.log(this.name);
}
}
function Cat(name) {
Animal.call(this, name)
}
Cat.prototype = new Animal();
let cat = new Cat('cat');
cat.getName()
3.组合继承
组合继承集合了原型链和盗用构造函数,将两者的优点集中起来,基本的思路是使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性,这样既可以把方法定义在原型上,实现重用,又可以让每个实例都有自己的属性。
function Animal(name) {
this.name = name;
this.color = ['yellow', 'black'];
}
Animal.prototype.getName = function () {
console.log(this.name);
}
function Bird(name, age) {
Animal.call(this, name);
this.age = age;
}
Bird.prototype = new Animal();
Bird.prototype.constructor = Bird;
let b1 = new Animal('bird1');
console.log(b1); //{"name":"bird1","color":["yellow","black"]}
let b2 = new Animal('bird2');
b2.color.push('white');
console.log(b2);{"name":"bird2","color":["yellow","black","white"]}
4.寄生组合继承
使用原型工厂封装继承
function extend(child, parent) {
child.prototype = Object.create(parent.prototype)
child.prototype.constructor = child;
}
function Animal(name, age) {
this.name = name;
this.age = age;
this.color = ['black', 'gray']
}
Animal.prototype.getColor = function () {
console.log(this.color);
}
function Dog(name, age) {
Animal.apply(this, [name, age])
}
extend(Dog, Animal)
let d = new Dog('Dh', 5);
console.log(d); // Dog {name: 'Dh', age: 5, color: Array(2)}
d.getColor(); // ['black', 'gray']
5.class类实现继承使用super关键字实现继承
- extends就是class类实现继承的核心。
- 子类必须在constructor方法中调用super方法,且super方法需要放到第一行。
class Animal {
constructor(name) {
this.name = name;
}
getName() {
console.log(this.name);;
}
}
class Dog extends Animal {
constructor(name, color) {
super(name)
this.color = color;
}
}
let d = new Dog('Dh', 'white');
console.log(d); // Dog {name: 'Dh', color: 'white'}
d.getName(); // Dh