在JavaScript中视频详细讲解了面向对象与原型的使用。对于面向对象,大家都应经很熟悉了,简单说一下面向对象的三大特性:封装、继承与多态。
封装就是:将对象的特性进行抽象,然后将抽象得到的数据和行为(或功能)相结合,形成一个类,而这个类不受外界的干扰。说白了就是将代码与数据进行捆绑,然后放在一个“黑匣子中”,这个“黑匣子”不会受到外界的干扰。
继承:就是继承父类所有的特点,作用就是避免重复,提高代码重用行。
多态:多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。个人理解就是同一消息,作用在不同的对象身上所产生不同结果的状态。
在JavaScript它是每个函数在创建时都会有的一个属性原型(prototype)。使用原型的好处可以让所有对象实例共享原型模式中的属性与方法。这既是原型模式的优点,也是原型模式的缺点。因为如果原型中的属性包含引用类型就会出现问题如下:
function Box(){};
Box.prototype={
Constructor:Box,
name:'Lee',
age:100,
family:['父亲','母亲','妹妹']; //添加数组
run:function(){
return this.name+this.age+this.family;
};
var box1=new Box();
box1.family.push('哥哥'); //实例原型中添加哥哥。
alert(box1.run()); //显示结果为:父亲、母亲、妹妹、哥哥
var box2=new Box(); //实例原型
alert(box2.famliy); //显示结果:父亲、母亲、妹妹、哥哥. 预想结果为:父亲、母亲、妹妹
}
通过Box2的显示结果可以看出,原型里的共享数据已经改变了。所以这导致了很多开发者放弃使用原型。
解决方式:
function Box(name,age){ //将所有信息封装到函数体内
this.name=name;
this.age=age;
if(typeof this.run!='function'){ //仅在第一次调用的初始化
Box.prototype.run=function(){
return this.name+this.age+'运行中。。。。';
};
}
}
var box=new Box('Lee',100);
alert(box.run());//显示结果:Lee100运行中。。。
var box1=new Box('Jeak',200);
alert(box1.run());//显示结果:jeak200运行中。。。
通过上面的方式不仅实现了决原型共享,又保持了属性的独立性。
下面说一下在JavaScript中的继承。在其他正统面向对象中继承都是有两种方式实现继承的。一种是接口,一种是继承。而在JavaScript中只支持继承而不支持接口,所以实现继承是依靠原型链来完成的。
在JavaScript中继承分为:原型式继承,组合继承、寄生式继承和寄生组合继承。原型链的继承流图如下:
组合继承是由原型链与借用构造函数构成。
示例:
function Box(age){
this.name=['Lee','Jack','Hello']
this.age=age;
}
Box.prototype.run=function(){
return this.name+this.age;
};
function Desk(age){
Box.call(this.age); //对象冒充
}
Desk.prototype=new Box(); //原型链继承
var desk=new Desk(100);
alert(desk.run());
原型继承:借助原型并基于已有的对象创建新对象,同
时还不必因此创建自定义类型。
示例:
function obj(o){ //创建字面量函数
function F(){}//创建一个构造函数
F.prototype=o; //把字面量函数赋值给构造函数原型
return new F();//最终返回出实例化的构造函数
}
var box={
name:'Lee',
arr:['哥哥','妹妹','姐姐'];
};
var box1=obj(box);
alert(box1.name);
box.name='Jack';
alert(box1.name);
alert(box1.arr);
box1.arr.push('父母');
var box2=obj(box);
alert(box2.name);
alert(box2.arr);
寄生式继承:是原型式与工厂模式相结合,目的是封建创建对象的过程。
示例:
function create(o){
var f=obj(o);
f.run=function(){
return this.arr;
<span style="white-space:pre"> </span>};
<span style="white-space:pre"> </span>return f;
};
function Box(name){
this.name=name;
this.arr['哥哥','妹妹','父母'];
}
box.prototype.run=function(){
return this.name;
};
function Desk(name,age){
Box.call(this,name);
this.age=age;
}
Desk.parototype=new Box();
寄生组合继承方式是解决两次调用的问题。
function obj(o){
function F(){}
F.prototype=o;
return new F();
}
function create(box,desk){
var f=obj(box.prototype);
f.constructor=desk;
desk.prototype=f;
}
function Box(name){
this.name=name;
this.arr['哥哥','妹妹','父母'];
}
Box.prototype.run=function(){
return this.name;
}
function Desk(name,age){
Box.call(this,name);
this.age=age;
}
inPrototype(Box,Desk);
var desk=new Desk('Lee',100);
desk.arr.push('姐姐');
alert(desk.arr);
alert(desk.run());
var desk2=new Desk('Jack',200);
alert(desk2.arr);