三.对象属性的封装(公有和私有)
以例子来说明:
functionList(){
varm_elements=[];//私有成员,在对象外无法访问 m_elements=Array.apply(m_elements,arguments);
//此处模拟getter,使用时alist.length;
//等价于getName()方式:this.length=function(){returnm_elements.length;},使用时alist.length();
//公有属性,可以通过"."运算符或下标来访问 this.length={
valueOf:function(){
returnm_elements.length;
},
toString:function(){
returnm_elements.length;
}
}
//公有方法,此方法使用得alert(alist)相当于alert(alist.toString())
this.toString=function(){ returnm_elements.toString();
}
//公有方法
this.add=function(){
m_elements.push.apply(m_elements,arguments);
}
//私有方法如下形式,这里涉及到了闭包的概念,接下来继续说明
//varadd=function()或functionadd()
//{
//m_elements.push.apply(m_elements,arguments);
//}
}
varalist=newList(1,2,3);
dwn(alist);//=alert(alist.toString()),输出1,2,3
dwn(alist.length);//输出3
alist.add(4,5,6);
dwn(alist);//输出1,2,3,4,5,6
dwn(alist.length);//输出6
varm_elements=[];//私有成员,在对象外无法访问 m_elements=Array.apply(m_elements,arguments);
//此处模拟getter,使用时alist.length;
//等价于getName()方式:this.length=function(){returnm_elements.length;},使用时alist.length();
//公有属性,可以通过"."运算符或下标来访问 this.length={
valueOf:function(){
returnm_elements.length;
},
toString:function(){
returnm_elements.length;
}
}
//公有方法,此方法使用得alert(alist)相当于alert(alist.toString())
this.toString=function(){ returnm_elements.toString();
}
//公有方法
this.add=function(){
m_elements.push.apply(m_elements,arguments);
}
//私有方法如下形式,这里涉及到了闭包的概念,接下来继续说明
//varadd=function()或functionadd()
//{
//m_elements.push.apply(m_elements,arguments);
//}
}
varalist=newList(1,2,3);
dwn(alist);//=alert(alist.toString()),输出1,2,3
dwn(alist.length);//输出3
alist.add(4,5,6);
dwn(alist);//输出1,2,3,4,5,6
dwn(alist.length);//输出6
四.属性和方法的类型
JavaScript里,对象的属性和方法支持4种不同的类型:privateproperty(私有属性),dynamicpublicproperty(动态公有属性),staticpublicproperty/prototypeproperty(静态公有属性或原型属性),staticproperty(静态属性或类属性)。私有属性对外界完全不具备访问性,可以通过内部的getter和setter(都是模拟);动态公有属性外界可以访问,每个对象实例持有一个副本,不会相互影响;原型属性每个对象实例共享唯一副本;类属性不作为实例的属性,只作为类的属性。以下是例子:
//动态公有类型,静态公有类型(原型属性) functionmyClass(){
varp=100;//privateproperty this.x=10;//dynamicpublicproperty
}
myClass.prototype.y=20;
//要想成为高级JavaScript阶段,prototype和闭包必须得理解和适当应用
myClass.z=30;//staticproperty
vara=newmyClass();
dwn(a.p)//undefined
dwn(a.x)//10
dwn(a.y)//20
a.x=20;
a.y=40;
dwn(a.x);//20
dwn(a.y);//40
delete(a.x);//删除对象a的属性x
delete(a.y);//删除对象a的属性y
dwn(a.x);//undefined
dwn(a.y);//20静态公有属性y被删除后还原为原型属性y
dwn(a.z);//undefined类属性无法通过对象访问
dwn(myClass.z);
varp=100;//privateproperty this.x=10;//dynamicpublicproperty
}
myClass.prototype.y=20;
//要想成为高级JavaScript阶段,prototype和闭包必须得理解和适当应用
myClass.z=30;//staticproperty
vara=newmyClass();
dwn(a.p)//undefined
dwn(a.x)//10
dwn(a.y)//20
a.x=20;
a.y=40;
dwn(a.x);//20
dwn(a.y);//40
delete(a.x);//删除对象a的属性x
delete(a.y);//删除对象a的属性y
dwn(a.x);//undefined
dwn(a.y);//20静态公有属性y被删除后还原为原型属性y
dwn(a.z);//undefined类属性无法通过对象访问
dwn(myClass.z);
五.原型(prototype)
这里只讲部分,prototype和闭包都不是几句话都能讲清楚的,如果这里可以给你一些启蒙,则万幸矣。习语”照猫画虎“,这里的猫就是原型,虎是类型,可以表示成:虎.prototype=某只猫or虎.prototype=new猫()。因为原型属性每个对象实例共享唯一副本,所以当实例中的一个调整了一个原型属性的值时,所有实例调用这个属性时都将发生变化,这点需要注意,以下是原型关系的类型链:
functionClassA(){ }
ClassA.prototype=newObject();
functionClassB(){ } ClassB.prototype=newClassA();
functionClassC(){ } ClassC.prototype=newClassB();
varobj=newClassC();
dwn(objinstanceofClassC);//true
dwn(objinstanceofClassB);//true
dwn(objinstanceofClassA);//true
dwn(objinstanceofObject);//true
带默认值的Point对象:
functionPoint2(x,y){
if(x)this.x=x;
if(y)this.y=y;
}
//设定Point2对象的x,y默认值为0 Point2.prototype.x=0;
Point2.prototype.y=0;
//p1是一个默认(0,0)的对象
varp1=newPoint2();//可以写成varp1=newPoint2也不会出错,WHY
//p2赋值
varp2=newPoint2(1,2);
dwn(p1.x+","+p1.y);//0,0
dwn(p2.x+","+p2.y);//1,2
delete对象的属性后,原型属性将回到初始化的状态: functionClassD(){
this.a=100;
this.b=200;
this.c=300 }
ClassD.prototype=newClassD();//将ClassD原有的属性设为原型,包括其值 ClassD.prototype.reset=function(){//将非原型属性删除
for(vareachinthis){
deletethis[each];
}
}
vard=newClassD();
dwn(d.a);//100
d.a*=2;
d.b*=2;
d.c*=2;
dwn(d.a);//200
dwn(d.b);//400
dwn(d.c);//600
d.reset();//删掉非原型属性,所有回来原型
dwn(d.a);//100
dwn(d.b);//200
dwn(d.c);//300
ClassA.prototype=newObject();
functionClassB(){ } ClassB.prototype=newClassA();
functionClassC(){ } ClassC.prototype=newClassB();
varobj=newClassC();
dwn(objinstanceofClassC);//true
dwn(objinstanceofClassB);//true
dwn(objinstanceofClassA);//true
dwn(objinstanceofObject);//true
带默认值的Point对象:
functionPoint2(x,y){
if(x)this.x=x;
if(y)this.y=y;
}
//设定Point2对象的x,y默认值为0 Point2.prototype.x=0;
Point2.prototype.y=0;
//p1是一个默认(0,0)的对象
varp1=newPoint2();//可以写成varp1=newPoint2也不会出错,WHY
//p2赋值
varp2=newPoint2(1,2);
dwn(p1.x+","+p1.y);//0,0
dwn(p2.x+","+p2.y);//1,2
delete对象的属性后,原型属性将回到初始化的状态: functionClassD(){
this.a=100;
this.b=200;
this.c=300 }
ClassD.prototype=newClassD();//将ClassD原有的属性设为原型,包括其值 ClassD.prototype.reset=function(){//将非原型属性删除
for(vareachinthis){
deletethis[each];
}
}
vard=newClassD();
dwn(d.a);//100
d.a*=2;
d.b*=2;
d.c*=2;
dwn(d.a);//200
dwn(d.b);//400
dwn(d.c);//600
d.reset();//删掉非原型属性,所有回来原型
dwn(d.a);//100
dwn(d.b);//200
dwn(d.c);//300