继承是面向对象的一大特征,
function gard() {
this.age = '100'
}
function parent(name) {
this.name = name
this.sex = '女'
this.ok = function() {console.log(this.name)}
}
function child(name){
this.name = name
}
这样时候 想要child 的实例对象可以访问到parent 和 gard 构造函数中的属性; 同时也想要parent的实例对象可以访问到gard中的属性; 我们知道 构造函数 new 一个对象是创建并初始化这个对象,构造函数的this 指向该对象;
1. 原型链继承 : 利用构造函数的原型prototype 指向 要继承的构造函数的实例对象, 实现链式继承;实现了原型对属性和方法的继承
如果我们访问一个对象的属性,肯定是先从自身查找,如果自身没有的话 ,往对应的构造函数的原型prototype上去找,如果还没有就往原型的原型去找,直到找到null
我们访问 创建一个child 实例 let childInstance = new child('childName')
childInstance .sex 时候 现在肯定是undefined
利用上面说的 如果childInstance 本身没有这个属性 那肯定往它对应的构造函数child.prototype(childInstance.__proto__)上去寻找,
目前child.prototype是没有的 ,再往child.prototype的构造函数 Object.prototype(child.prototype.__proto__)上去寻找 找到null
所以这个时候思考: 在child.prototype 没有找到的时候 ,我们让child.prototype 指向parent的实例对象(关键点) 即: child.prototype = new parent()
这个时候 childInstance.sex 就可以获取到了 , parent的实例对象可以访问到gard中的属性 也同理
function gard() {
this.age = '100'
}
function parent(name) {
this.name = name
this.sex = '女'
this.ok = function() {console.log(this.name)}
}
function child(name){
this.name = name
}
child.prototype = new parent()
parent.prototype = new gard()
let childInstance = new child()
let parentInstance = new parent()
childInstance
child {name: undefined}
childInstance.__proto__
gard {name: undefined, sex: '女', ok: ƒ}
childInstance.sex
输出:'女'
parentInstance
parent {name: undefined, sex: '女', ok: ƒ}
parentInstance.__proto__
gard {age: '100'}
parentInstance.age
输出:'100'
2. 构造函数继承: 要继承的构造函数创建实例对象时改变指向 call ,实现对象 拥有继承的属性;实现了 构造函数实例对象对属性和方法的继承
function gard() {
this.age = '100'
}
function parent(name) {
gard.call(this, name)
this.name = name
this.sex = '女'
this.ok = function() {console.log(this.name)}
}
function child(name){
parent.call(this, name)
this.name = name
}
let childInstance = new child()
let parentInstance = new parent()
childInstance
child {age: '100', name: undefined, sex: '女', ok: ƒ}
childInstance.sex
输出:'女'
parentInstance
parent {age: '100', name: undefined, sex: '女', ok: ƒ}
parentInstance.age
输出:'100'
3. 组合继承
function parent(name) {
this.name = name
this.sex = '女'
this.ok = function() {console.log(this.name)}
}
parent.prototype.say = function () {
console.log('saysay')
}
function child(name) {
parent.call(this, name) // 继承父类的自身属性 ,这个不能继承原型上的属性或者方法
this.name = name
}
child.prototype = Object.create(parent.prototype) // 创建的新对象的原型对象指向parent.prototye 即: child.prototype.__prto__ = parent.prototye
child.prototype.constructor = child // 上面修改child.prototype的原型对象指向时也修改了构造函数的指向, 需要修改下
let childInstance = new child('小明')
console.log(childInstance.sex)
console.log(childInstance.say())