继承方式:构造函数继承,原型继承,组合继承,寄生式继承,寄生式组合继承
注:本篇博客可能存在理解错误,仅供参考,新手小菜鸡
在说继承之前,先来说说原型链吧。
说到原型链,你能想到什么?
构造函数?原型对象?实例?
他们之间的关系又是什么呢?
构造函数可以通过new创建出一个实例对象(可见上篇博客new做了什么),
实例对象又能通过__proto__访问原型对象,而原型对象又可以通过constructor访问其构造函数,构造函数可以通过prototype访问原型对象。
是不是很绕,对的,确实很绕。
那接下来看下他们的三角关系吧
确实很丑hhh
接下来说下构造函数继承吧
// 缺点:原型链上的方法和属性无法继承
function Person(){
this.name = 'zhangsan';
this.say = function(){
console.log('say way');
}
}
// S1里没有这个方法
Person.prototype.run = function(){
console.log('run way');
}
function Student(){
Person.call(this)//构造函数继承的关键代码
this.sex = 'man'
}
var s1 = new Student()
console.log(s1);
关键代码就是Person.call(this)//构造函数继承的关键代码
在子类的构造函数里执行父类的构造函数,因此继承了构造函数里面的方法和属性。
但是它能继承构造函数原型对象的方法吗?
很明显不能。
原型继承
是指原型的继承,而不是构造函数原型的继承。
//原型链的继承
//缺点:复杂数据类型是以引用的形式存在,即只改一个其余也跟着变
// function Person(){
// this.name = 'zhangsan';
// this.arr = [1,2]
// this.say = function(){
// console.log('say way');
// }
// }
// Person.prototype.run = function(){
// console.log('run method');
// }
// function Student(){
// this.sex = 'man'
// }
// // Student.prototype = Person.prototype
//错误做法,改变了构造函数的原型,它的construct不再指向student,而且会共用一个原型
// //继承是指原型的继承
// Student.prototype.__proto__ = new Person() //这个写法也可以,不过多走了一层,画图可能好理解点
// //Student.prototype.__proto__ = Person.prototype
// var s1 = new Student();
// var s2 = new Student()
// s1.arr.push(22)
// console.log(s1.arr);
// console.log(s2.arr);
// s1.run()
组合继承
// 组合式继承
//构造函数继承属性,原型继承方法
// function Person() {
// this.name = "person"
// this.arr = [1, 2]
// this.say = function () {
// console.log('say')
// }
// }
// Person.prototype.run = function () {
// console.log('run')
// }
// Person.prototype.hobby = '吃饭'
// function Student() {
// Person.call(this)
// this.age = 19
// }
// Student.prototype.__proto__ = Person.prototype
// var s1 = new Student()
// var s2 = new Student()
// s1.arr.push(2222)
// console.log(s1);