一个类,总有一些内部的特殊实现细节,这些细节不宜被外部获知并访问,这就是OOP中的私有访问限制符的意义.JavaScript没有提供实现此机制的支持,但我们可以通过一些技巧来另行实现.
在前面几节,我们定义的类的属性和方法,统一都是公开的,即通过类的实例对象都能访问到.
让我们首先定义一个具有私有属性和方法的类吧,如下:
//声明People类
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
var People = function(name,isMan,age)
{
//设置私有成员:不用this索引器声明的对象就是私有的
//私有方法
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
function dec()
{ //检查secret实例变量,限制对象使用三次.
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (secret > 0)
{
secret--;
return true;
}
else
return false;
}
//私有属性
var secret = 3;
this.name = name || "none"; //string
this.sex = isMan || false; //bool
this.age = age || 0; //int
}
这里发现,在People类的定义中,secret属性和dec()方法前都没有用this关键字声明,这就声明了"私有"的对象了.
私有对象声明好之后,就需要通过公开的方法或属性简洁操纵,否则就没有意义了.
下面通过一个公开方法toString,来简洁操纵实例的私有对象,如下:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
var People = function(name,isMan,age)
{
//设置私有成员:不用this索引器声明的对象就是私有的
//私有方法
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
function dec()
{ //检查secret实例变量,限制对象使用三次.
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (secret > 0)
{
secret--;
return true;
}
else
return false;
}
//私有属性
var secret = 3;
this.name = name || "none"; //string
this.sex = isMan || false; //bool
this.age = age || 0; //int
//定义在类内部的公开方法与在类外部的公开方法不同.
//内部的能访问私有对象,而外部的则不能.
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.toString = function()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (dec())
{
return this.name + "&" + this.sex + "&" + this.age + "&" + secret; //这里不能使用this索引器.
}
else
return null;
}
}
// People.prototype.show(){
// alert(this.secret); //在类外部定义的公开方法,不能访问类的私有属性,将会运行出错.
// }
呵呵,前面我们通过在类内部的this.toString = function(){...}和People.prototype.String = function(){...}来定义好象完全相同功能的toString方法.这里就显示出来区别了.
在类内部通过this索引器定义的公开方法,能访问类内部的私有对象,而类外部通过prototype定义的公开方法则不能.
下面是完整的示例代码:
<script type="text/javascript">
//声明People类
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
var People = function(name,isMan,age)
{
//设置私有成员:不用this索引器声明的对象就是私有的
//私有方法
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
function dec()
{ //检查secret实例变量,限制对象使用三次.
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (secret > 0)
{
secret--;
return true;
}
else
return false;
}
//私有属性
var secret = 3;
this.name = name || "none"; //string
this.sex = isMan || false; //bool
this.age = age || 0; //int
//定义在类内部的公开方法与在类外部的公开方法不同.
//内部的能访问私有对象,而外部的则不能.
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
this.toString = function()
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (dec())
{
return this.name + "&" + this.sex + "&" + this.age + "&" + secret; //这里不能使用this索引器.
}
else
return null;
}
}
// People.prototype.show(){
// alert(this.secret); //在类外部定义的公开方法,不能访问类的私有属性,将会运行出错.
// }
var p = new People("fanrong",true,24);
alert(p.toString());
alert(p.toString());
alert(p.toString());
alert(p.toString()); //当访问第四遍时,由于p对象内部的私有变量secret<0,返回null.(即不允许访问了)
</script>