@author YHC
如果你是js大牛此文章对你无意义:
转载必须注明原文地址:http://blog.csdn.net/yhc13429826359/article/details/8153820
js继承大致可分为
类式继承:
原型继承:
以下就是原型继承一个小小的示例:
//原型式继承
//使用原型继承,并不需要用类来定义对象结构那么复杂
//直接创建对象即可,这个对象可以在clone之后可以被
//新的对象重用,这个也是利用原型链的工作机制.
//定义Perosn原型对象
var Person={
name:'default name',
getName:function(){
return this.name;
}
};
//克隆并创建对象
var p=clone(Person);
alert(p.getName());//结果:default name
p.name='new name';
alert(p.getName());//结果:new name
//定义 学生类继承Perosn类
var Student=clone(Person);
//新增属性和方法
Student.score=50;
Student.getScore=function(){
//在这里用到父类的方法
return this.getName()+":"+this.score+"分";
};
alert(Student.getScore());//default name:50分
//===============继承而来的成员读和写的不对等性=======================
//添加新的属性和方法,演示:继承而来的成员读和写的不对等性
Student.books=['Greek'];//注意:默认值
Student.getBooks=function(){
return this.books;
};
//定义学生数组
var students=[];
//学生 ZS,注意:====>没有修改books属性默认值
students[0]=clone(Student);
students[0].name='ZS';
//学生LS,注意:===>修改了books属性的默认值
students[1]=clone(Student);
students[1].name='LS';
students[1].books.push('Chinese');//注意:===>这种赋值方式不是重新定义,而是直接使用
students[1].books.push('French');
//输出结果:
alert(students[0].getBooks());//结果:Greek,Chinese,French
alert(students[1].getBooks());//结果:Greek,Chinese,French
//这里也许就有人想说why? 第一个学生对象students[0]没有
//修改books属性那么应该显示默认值Greek,为什么会多出两个
//Chinese,French,这个应该是students[1]的属性为什么
//跑到students[0]对象属性上面去了咧?????
//解释
//在上面的例子中students[1].books.push添加元素实际上
//是把这个元素添加到Student.books属性中了,在调用students[1].books.push()的时候
//没有在students[1]显示定义books属性,那么就是找到其原型对象的同名属性
//那么这也就意味这这个值的修改不仅影响了Student,也会影响到所有继承了Student而且还改写
//这个属性的默认值对象
//解决方案
//在改变所有的数组和对象成员之前先创建新副本,这种问题属于逻辑错误,非常难调试
//例如以上代码可以改为以下:
//students[1].books=[]; 注意:先创建新副本,这样就可以避免向原型对象继续查找,而修改原型对象属性
//students[1].books.push('Chinese');
// students[1].books.push('French');
//克隆一个js对象
function clone(obj){
//创建新的空函数F
function F(){};
//设置F的原型对象为传入的我们定义的原型对象
//prototype属性指向原型对象,通过原型链机制,它提供继承来的类的连接
F.prototype=obj;
//返回克隆原型对象的空对象
return new F;
}