通过es6实现继承
// es6继承
class Animal {
constructor(name, age) {
this.name = name
this.age = age
}
eat() {
console.log('eat');
}
}
class Dog extends Animal {
constructor(name, age, food) {
super(name, age) //相当于调用了父构造函数,必须在 this.food = food 之前调用
this.food = food
}
say() {
console.log('say');
}
}
const dog = new Dog('二哈', 3, '肉');
console.log(dog);
dog.eat();
dog.say();
借用父构造函数继承
- 继承属性
function Animal(name, age) {
// this 指向 父构造函数的实例对象
this.name = name
this.age = age
}
function Dog(name, age, food) {
// this 指向子构造函数的对象实例
Animal.call(this, name, age)
this.food = food
}
const dog2 = new Dog('金毛', 4, '狗粮');
console.log(dog2);
- 继承方法
通过 Dog.prototype = Animal.prototype
问题1:Dog.prototype上声明的方法,Animal.prototype也存在,他们都是指向Animal.prototype的
function Animal(name, age) {
// this 指向 父构造函数的实例对象
this.name = name
this.age = age
}
Animal.prototype.eat = function () {
console.log('eat');
}
function Dog(name, age, food) {
// this 指向子构造函数的对象实例
Animal.call(this, name, age)
this.food = food
}
// 继承方法
Dog.prototype = Animal.prototype //这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Dog.prototype.say = function () {
console.log('say');
}
const dog2 = new Dog('金毛', 4, '狗粮');
// console.log(dog2);
console.log(Animal.prototype);
通过 Dog.prototype = new Animal()
问题2:虽然子构造函数原型继承了父构造函数原型上的方法,也不影响父构造函数原型。但是 Dog.prototype = new Animal() 相当于 Dog.prototype = {…},会覆盖掉里面的方法、构造函数等。
function Animal(name, age) {
// this 指向 父构造函数的实例对象
this.name = name
this.age = age
}
Animal.prototype.eat = function () {
console.log('eat');
}
function Dog(name, age, food) {
// this 指向子构造函数的对象实例
Animal.call(this, name, age)
this.food = food
}
Dog.prototype = new Animal()
// dog2.__proto__ --> Dog.prototype --> new Animal().__proto__ --> Animal.prototype
Dog.prototype.say = function () {
console.log('say');
}
const dog2 = new Dog('金毛', 4, '狗粮');
console.log(Animal.prototype);
console.log(Dog.prototype);
- 解决
通过Dog.prototype.constructor = Dog,让构造函数重新指向Dog
function Animal(name, age) {
// this 指向 父构造函数的实例对象
this.name = name
this.age = age
}
Animal.prototype.eat = function () {
console.log('eat');
}
function Dog(name, age, food) {
// this 指向子构造函数的对象实例
Animal.call(this, name, age)
this.food = food
}
// 继承方法
// Dog.prototype = Animal.prototype //这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Dog.prototype = new Animal()
// dog2.__proto__ --> Dog.prototype --> new Animal().__proto__ --> Animal.prototype
Dog.prototype.constructor = Dog
// // 如果利用对象形式修改了原型对象,一定要用 constructor 指回原来的构造函数
Dog.prototype.say = function () {
console.log('say');
}
const dog2 = new Dog('金毛', 4, '狗粮');
// console.log(dog2);
console.log(Animal.prototype);
console.log(Dog.prototype);
console.log(Dog.prototype.constructor);