基础知识点:1.原型链的读取规则;2.原型链中prototype和constructor的属性;3.原型链中prototype和constructor的指针指向。
1. 原型链继承
基本思想:是利用原型让一个引用类型继承另一个引用类型的属性和方法。
function SuperType(){
this.name = 'father'
this.age = '45'
}
SuperType.prototype.getName = function(){
console.log(this.name)
}
function SubType(){
this.name = 'son'
SuperType.call(this)
}
SubType.prototype = new SuperType()
SubType.prototype.getAge = function (){
console.log(this.age)
}
let subType = new SubType()
console.log(subType)
subType.getAge()
subType.getName()
以上代码定义了两个类型:SuperType和SubType。每个类型分别有一个属性和方法。他们的主要区别是SubType继承了SuperType, 而继承是通过创建SuperType的实例,并将该实例赋给SubType.prototype实现的。 实现的本质是重写原型对象,代之以一个新类型的实例。
最终结果是 实例subType指向SubType的原型,SubType的原型又指向SuperType的原型。
注意:通过原型链实现继承时,不能使用对象字面量创建原型方法。因为这样做就会重写原型链。
- 实现了什么?
实现了继承超类的属性和方法。
- 原型继承时发生了什么?
在通过原型来实现继承时,原型实际上会变成另一个类型的实例。于是,原来的实例属性( new SuperType() )也就顺理成章地变成了现在的原型属性了。
- 原型链问题?
主要问题来自包含引用类型值的原型,引用类型值的原型属性会被所有实例共享; 而这也正是为什么要在构造函数中,而不是在原型对象中定义属性的原因。(原型链可以所有实例的属性和方法共享。有些属性值希望不同实例有不同的值,而只用原型链实现继承得不到想要的效果。需要配合构造函数来实现。)
借用构造函数继承
基本思想: 在子类型构造函数的内部调用超类型构造函数。(函数只不过实在特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在(将来)新创建的对象上执行构造函数。
function SuperType(name){
this.name = name;
}
function SubType(){
SubType.call(this,'lis')
this.age = 29;
}
var subtype = new SubType();
console.log(subtype.name); //lis
console.log(subtype.age); //29
- 实现了什么?
子类型中可以通过语法使用共享超类型的属性和方法。
- 借用构造函数的问题?
如果仅仅是借用构造函数,那么也就无法避免构造函数模式存在的问题 — 方法都在构造函数中定义,因此函数服用就无从谈起了。而且,在超类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。 考虑到这些问题,借用构造函数的技术也是很少单独使用的。
组合继承
组合继承:指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。
思路:使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
好处:即通过在原型上定义方法实现了函数服用,又能够保证每个实例都有他自己的属性。
function SuperType(name){
this.name = name;
this.colors = ['red','green']
}
SuperType.prototype.sayName = function(){
console.log(this.name)
}
function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.getAge = function(){
console.log(this.age)
}
let subtype = new SubType('lisi', 29)
console.log(subtype)
console.log(subtype.colors)
subtype.sayName()
subtype.getAge()