继承发展史
- 传统形式-->原型链
过多的继承没有用的属性
2.借用构造函数
不能继承借用构造函数的原型
每次构造函数都要多走一个函数
3.共享原型
不能随便改动自己的原型
4.圣杯模型
1.传统形式-->原型链
Grand.prototype.lastName = "ji";
function Grand(){
}
var grand = new Grand();
Father.prototype = grand;
function Father(){
this.name = "hehe";
}
var father = new Father();
Son.prototype = father;
function Son(){
}
var son = new Son();
通过原型链的继承,产生了三个原型链,现在主要是继承原型链的顶端lastName属性,但是由于形成了原型链,一系列的都连成了一条链,继承了下来,也就是说,son现在既能继承father的东西,也能继承father原型的东西,又能继承grand的东西,还能继承grand原型的东西,一些列的都继承了,那现在从头继承到尾就会发生一些矛盾,就是我想继承来的继承来了,我不想继承来的东西他也继承来了,就会造成无论是效率还是用法上的一些浪费,所以第一种方法很快就被废弃了。
2.借用构造函数
不能继承借用构造函数的原型
每次构造函数都要多走一个函数
function Person(name,age,sex){
this.name = name;
this.age = =age;
this.sex = sex;
}
function Student (name,age,sex,grade) {
}
现在我想构造student这个构造函数,之前的函数已经形成了一部分功能,我之后就没必要把所有的功能写到自己身上吧,用别人的东西干我的事(这并不算是继承),
function Person(name,age,sex){
this.name = name;
this.age = =age;
this.sex = sex;
}
function Student (name,age,sex,grade) {
Person.call(this,name,age,sex);
this.grade = grade;
}
var student = new Student();
把this放进去有个前提就是,你这个函数必须得是new出来的!!
这个第二种方法也有不好的地方,你只能借用构造函数的方法,你不能用人家的原型。
每次执行构造函数多走了一个函数,你每构造一个对象都要执行一个student还有一个person吧,你是从视觉上省了代码的量,但是运行上根本就没省吧,而且还更加复杂了,多增加了一个函数调用。
这个1不算是继承,2它也挺麻烦的,所以不把他们算作标准的继承模式
3.标准的继承模式--------公有原型
Father.prototype.lastName = "deng";
function Father(){
}
function Son (){
}
我们现在想让son生产出的对象继承自father的prototype,怎么办呢?
按原来的的方法是不是原型链,
现在:
Father.prototype.lastName = "deng";
function Father(){
}
function Son (){
}
Son.prototype = Father.prototype;
var son = new Son();
那在后面加一条var father = new Father();
是不是也是deng啊
这两个构造函数就有一个原型了,所以这两个函数生产出来的对象就继承自同一个原型吧。如果说a继承b的话,就这么来写。
咱可以封装一个函数,把他封装起来,怎么办呢,实现一个继承?
要学会抽象出一个功能,封装成一个函数。函数就代表功能,函数代表功能的复用。
Inherit 继承的意思,他也是css属性的一个指呢,这个值是继承值的意思。
function inherit(Target,Origin){
}
Origin原始的,target继承origin,这两个东西传进来的得是构造函数,咱不是想让一个对象去继承某一个东西,咱最终是想让一个构造函数去继承某一个东西,这样这个构造函数生产出的对象就全继承自那个对象了吧,这是根上的问题。
Father.prototype.lastName = "deng";
function Father(){
}
function Son (){
}
function inherit(Target,Origin){
Target.prototype = Origin.prototype;
}
这不就完事了吗?
Father.prototype.lastName = "deng";
function Father(){
}
function Son (){
}
function inherit(Target,Origin){
Target.prototype = Origin.prototype;
}
inherit(Son,Father);
var son = new Son();
现在有个问题,我让这个继承这样实现
var son = new Son();
inherit(Son,Father);
还好使吗?因为他先继承了之后,你后改的原型。
他继承的还是他原来的原型的空间。一定得是先继承后用它。
不足:
比如,现在 son用的是father的prototype,son想给自己的原型上多增加一些属性,方便我后面生产出来的对象使用,他只能是
inherit(Son,Father);
Son.prototype.sex = "male";
var son = new Son();
这是不是好使了,
,但是,你如果在后面在加上
var father = new Father();
son是这么改了,father也跟着改了!!!
现在son.prototype和father.prototype指向的是一个空间,你给自己那个空间加东西,
我的也变了,所以现在son想实现一个性化的东西,想加个原型啊,就根本不行吧,
因为你一改,就把人家给改了,你不能改人家的东西啊。
所以我现在想,我想继承自你,但我有不能影响你,这才是一个完美的形式,我有我自己定义的原型,我又有你给我提供的一个原型。
4.所以就引出了最后一种模式————圣杯模式。