浅谈javascript“面向对象”:
所谓面向对象oo语言就是能够创建自己专用的类或者对象,封装一组属性和行为。
=======================================================
js几种面向对象写法分析:
1.早期模式:
var Person = new Object;
Person.name = "zs";
Person.sex = 'boy';
Person.birthday = '2001-02-03';
Person.sayHi = function()
{
alert("Hi ! I am "+this.name);
}
使用方式:Person.sayHi()
优点:简单创建易于理解,单一功能使用方便
缺点:多创建几个该对象就要重复定制定义Person原对象。代码没有封装面向对象性。不能接受参数
---------------------------------------------------------------------------------------------------------------------------------------
2.工厂模式:
function Person(name,age,sex){
var o=new Object();
o.name=name;
o.age=age;
o.sex=sex;
o.sayHi=function(){
alert(this.name);
}
return o;
}
使用方式:var newPerson= Person('lucy',11,'girl');newPerson.sayHi();
优点:可以接受参数构建对象,可以被多次重复调用。
缺点:没有解决对象识别问题(仅仅是一个普通function对象)
-------------------------------------------------------------------------------------------------------------------------------
3.构造函数模式:
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.sayHi=function(){
alert(this.name)
}
}
使用方式:var newPerson=new Person('lucy',11,'girl');newPerson.sayHi();
分析:new的过程实际是一个对象实例化过程,newPerson是保存Person对象的一个实例,该实例就拥有了一个构造函数属性指向Person对象:newPerson.constructor==Person;
优点:没有显式创建对象,解决工厂模式对象无法识别问题(将实例标示为一种特定类型)。用new创建新实例,将作用域赋予新对象(否则执行指针指向window)
缺点:正是由于new时候this指针改变指向新实例,这时候新实例的方法也要重建。(sayHi原本是window的实例,new之后改变指向)每个实例都包含一个各自的sayHi函数对象。
即每次实例化该对象同时将原对象的sayHi也实例化一次。故本来方法一样的函数对象由于实例化导致每个实例的sayHi方法是不相等的。即在内存中每个新实例都有一份自己的专属sayHi方法,
本来就是公共方法,私有化没必要浪费内存。
---------------------------------------------------------------------------------------------------------------------------------
4.原型模式:
function Person(name,age,sex){
}
Person.prototype={
constructor:Person,
name:'lucy',
age:11,
sex:"girl",
sayHi:function(){
alert(this.name)
}
}
使用方式:var newPerson=new Person();newPerson.sayHi();
分析:创建的函数Person有一个prototype属性,该属性是一个指针,指向一个对象,该对象包含所有实例可以共享的属性和方法。也就是说 实例共享的属性以及方法不必放到构造函数中,
而是直接添加到构造函数的原型对象中。而且所有实例都可以改变该对象中的属性或者方法,并且在其他实例中同样生效。
优点:新对象的属性和方法是由所有实例共享的,即:即使创建多个newPerson 他们的sayHi函数是同一组的,都指向Person的prototype,不必重复创建sayHi函数对象(函数也是对象);
缺点:原型对象中的优点也是他的缺点,即 其中的公共属性在实例化时候不可能每次实例化时候都是相同的,假设有个原型属性type为array 那么在实例化时候 都指向同一个array
改变其中任何一个的值 原型对象中的该数组也会改变。扩展(clone)
-----------------------------------------------------------------------------------------------------------------------
5.混合模式:
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
Person.prototype={
constructor:Person,
sayHi:function(){
alert(this.name)
}
}
分析:结合了构造函数的实例私有化属性以及共享原型对象的公共方法,在可以任意创建不同对象实例基础上从而节省了内存占用空间。任何实例之间不会影响公共属性,从而解决原型模式的问题