1.原型链继承
优点:父类方法可以复用
缺点:1.父类所有的引用类型数据(对象,数组)会被子类共享,更改一个子类数据,其他子类数据会收到影响,一直变化
function Person1() {
// console.log(this)
this.name = '路人1';
this.age = 18;
this.getName = function(){
console.log(this.name)
}
}
Person1.prototype.get = ()=>{
console.log('Person1.prototype')
}
function Student(){
}
Student.prototype = new Person1();
let stu = new Student();
stu.name = '路人2'
stu.age = 21
console.log(stu.name)
console.log(stu.age)
stu.getName()
stu.get()
console.log('----------') //分割线
let stu2 = new Student();
console.log(stu2.name)
console.log(stu2.age)
stu2.getName()
stu2.get()
2.借用构造函数继承(伪造对象、经典继承)
优点:子类的引用类型的数据不会被子类共享,不会互相影响
缺点:子类的不能访问父类原型上的方法 (不能继承原型属性/方法,只能继承父类的实例属性和方法)
function Person1() {
// console.log(this)
this.name = '路人1';
this.age = 18;
this.getName = function(){
console.log(this.name)
}
}
Person1.prototype.get = ()=>{
console.log('Person1.prototype')
}
function Student(){
Person1.call(this) //改变person1的this指向
}
// Student.prototype = new Person1();
let stu = new Student();
stu.name = '路人2'
stu.age = 21
console.log(stu.name)
console.log(stu.age)
stu.getName()
// stu.get() get是Person原型上的方法 无法访问到
console.log('----------') //分割线
let stu2 = new Student();
console.log(stu2.name)
console.log(stu2.age)
stu2.getName()
// stu2.get()
3.组合式继承
原型链继承+借用构造函数继承
虽然他解决了上面两种继承方法的缺点,但是他复用了两次父类,产生了两份实例所以影响性能
function Person1() {
// console.log(this)
this.name = '路人1';
this.age = 18;
this.getName = function(){
console.log(this.name)
}
}
Person1.prototype.get = ()=>{
console.log('Person1.prototype')
}
function Student(){
Person1.call(this)
}
Student.prototype = new Person1();
let stu = new Student();
stu.name = '路人2'
stu.age = 21
console.log(stu.name)
console.log(stu.age)
stu.getName()
stu.get()
console.log('----------') //分割线
let stu2 = new Student();
console.log(stu2.name)
console.log(stu2.age)
stu2.getName()
stu2.get()
console.log(stu2)
4.寄生组合继承
完善第二种继承方法构造函数继承,根本思想就是将父类的原型属性使用一个容器存储,然后再将容器交给实例对象
function Person1() {
// console.log(this)
this.name = '路人1';
this.age = 18;
this.getName = function () {
console.log(this.name)
}
}
Person1.prototype.get = () => {
console.log('Person1.prototype')
}
function Student() {
Person1.call(this)
}
// Student.prototype = new Person1();
//寄生函数
const fn = function () { }
fn.prototype = Person1.prototype;
Student.prototype = new fn();
let stu = new Student();
stu.name = '路人2'
stu.age = 21
console.log(stu.name)
console.log(stu.age)
stu.getName()
stu.get()
console.log('----------') //分割线
let stu2 = new Student();
console.log(stu2.name)
console.log(stu2.age)
stu2.getName()
stu2.get()
console.log(stu2)
这样就完美解决了
5.ES6的继承
class Person1 {
constructor() {
this.name = '路人1';
this.age = 18;
this.getName = function () {
console.log(this.name)
}
}
get = () => {
console.log('Person1.prototype')
}
}
class Student extends Person1 { }
const stu = new Student();
stu.name = '路人2'
stu.age = 21
console.log(stu.name)
console.log(stu.age)
stu.getName()
stu.get()
console.log('----------') //分割线
let stu2 = new Student();
console.log(stu2.name)
console.log(stu2.age)
stu2.getName()
stu2.get()
console.log(stu2)
tu.get()
console.log('----------') //分割线
let stu2 = new Student();
console.log(stu2.name)
console.log(stu2.age)
stu2.getName()
stu2.get()
console.log(stu2)
什么问题都没有