一.每个方法function都有原型prototype属性,这个属性是构造方法构造出来的对象的公有祖先
当使用构造函数new出对象时,隐式地在构造方法开头添加var this = {__proto__ = 构造函数名.prototype},在函数末尾加上return this.
***子类只可以访问父类的属性但不能修改,如果修改那么会在自己的属性上加
二.继承的发展史
1.传统形式-->原型链
Father.prototype.lastname = 'cao';
function Father(){
}
var father = new Father();
Son.prototype = father;
function Son(){
}
var son = new Son();
此时对象son继承了father
2.借用构造函数
function Person(name, age, sex) {
this.name = name;
this.age = age;
thi.sex = sex;
}
function Student(name, age, sex, id) {
Person.call(this, name, age, sex);
this.id = id;
}
此时个方法的缺点:1.此时Person和Student逻辑上没有继承关系,只是Student调用了Person的方法,Student构建出来的对象的__proto__属性不是Person 2.每次构造都要执行两次函数
3.共享原型
Father.prototype.lastname = {};
function Father(){
}
function Son(){
}
Son.prototype = Father.prototype;
此时Son和Father共用一个原型。方法的缺点:如果给其中一个原型增加一个属性(Son.prototype.sex = 'male')那么Father的原型上也会加一个sex属性;
4.圣杯模式
function F () {
}
F.prototype = Father.prototype;
Son.prototype = new F();
Son.prototype.constuctor = Son;//将他的构造器归位,不然Son.constructor = Father
Son.prototype.uber = Father.prototype;//指出Son的超类(他真正继承自谁)
这样的好处:用一个F做中间层,Son的原型是新的F对象,这个对象上没有属性,当在Son的原型上增加属性时Father的原型不变,但是Son也可以通过自己原型(F构造的对象)的原型来访问Father原型的属性。