JavaScript中没有“私有成员”的概念,但却有“私有变量”的概念。
私有变量包括函数参数、局部变量和定义在函数内部的函数。私有变量
只能在函数内部访问,不能在外部访问。闭包可以访问私有变量。
  
利用这个特点,可以在对象上定义公共方法访问对象的私有变量,
这种公共方法被称作“特权方法”。利用这种模式,能够隐藏不可以被直
接改变的数据。
  
有两种定义特权方法的方式:第一种方式是在对象的构造函数内定
义,如:

     
functionMyObject()
     
{
        
//private variables and functions
         varprivateVariable=10;
        
functionprivateFunction()
        
{
           
returnfalse;
        
}
        
//privileged methods
         this.publicMethod=function()
        
{
           
privateVariable++;
           
returnprivateFunction();
        
};
     
}

  
因为构造函数模式所产生的方法不能在多个实例间共享,使用静
态私有变量可以解决这个问题。

1.静态私有变量

  
特权函数可以通过函数表达式来实现。函数表达式产生私有作用域,
其内部定义的私有变量将在对象的各实例间共享,因而成为静态私有变
量。函数表达式内定义的对象方法成为特权方法(也是闭包),可以访问
私有变量。对象的构造函数使用命名函数表达式定义,但不使用var
键字声明,这样可以在全局范围内访问,不过,这样做在严格模式下会
产生错误。如:

     
(function()
     
{
        
//private variables and functions
         varprivateVariable=10;
        
functionprivateFunction()
        
{
           
returnfalse;
        
}
        
//constructor
         MyObject=function()
        
{
        
};
        
//public and privileged methods
         MyObject.prototype.publicMethod=function()
        
{
           
privateVariable++;
           
returnprivateFunction();
        
};
     
})();

  
这种模式的私有变量和公共方法都会在所有实例间共享,如:

     
(function()
     
{
        
varname="";
        
Person=function(value)
        
{
           
name=value;
        
};
        
Person.prototype.getName=function()
        
{
           
returnname;
        
};
        
Person.prototype.setName=function(value)
        
{
           
name=value;
        
};
     
})();
     
varperson1=newPerson("Nicholas");
     
alert(person1.getName());   //"Nicholas"
      person1.setName("Greg");
     
alert(person1.getName());   //"Greg"

     
varperson2=newPerson("Michael");
     
alert(person1.getName());   //"Michael"
      alert(person2.getName());   //"Michael"

2.模块模式

  
模块模式也是一种单例模式。单例模式在JavaScript中通常使用下
面的方法产生:

     
varsingleton={
        
name:value,
        
method:function()
        
{
           
//method code here
         }
     
};

  
模块模式是对单例模式的提高,包含了私有变量和特权方法。如:

     
varsingleton=function()
     
{
        
//private variables and functions
         varprivateVariable=10;
        
functionprivateFunction()
        
{
           
returnfalse;
        
}
        
//privileged/public methods and properties
         return{
           
publicProperty:true,
           
publicMethod:function()
           
{
              
privateVariable++;
              
returnprivateFunction();
           
}
        
};
     
}();

  
模块模式在单例模式需要进行初始化和访问私有变量时很有用。在
Web应用程序中,通常使用单例模式管理应用程序级的信息。如:

     
functionBaseComponent()
     
{
     
}
     
functionOtherComponent()
     
{
     
}
     
varapplication=function()
     
{
        
//private variables and functions
         varcomponents=newArray();
        
//initialization
         components.push(newBaseComponent());
        
//public interface
         return{
           
getComponentCount:function()
           
{
              
returncomponents.length;
           
},
           
registerComponent:function(component)
           
{
              
if(typeofcomponent=="object")
              
{
                 
components.push(component);
              
}
           
}
        
};
     
}();
     
application.registerComponent(newOtherComponent());
     
alert(application.getComponentCount());  //2

  
模块模式的实例都是Object,不能使用instanceof运算符有效地
判断类型。

3.模块增强模式

  
这也是一种模块模式,但在返回所产生的对象之前,可以向其添加
属性和/或方法。如:

     
varsingleton=function()
     
{
        
//private variables and functions
         varprivateVariable=10;
        
functionprivateFunction()
        
{
           
returnfalse;
        
}
        
//create object
         varobject=newCustomType();
        
//add privileged/public properties and methods
         object.publicProperty=true;
        
object.publicMethod=function()
        
{
           
privateVariable++;
           
returnprivateFunction();
        
};
        
//return the object
         returnobject;
     
}();

  
在模块模式中,如果application对象需要是一个BaseComponent
实例,可以使用下面的方式:

     
functionBaseComponent()
     
{
     
}
     
functionOtherComponent()
     
{
     
}
     
varapplication=function()
     
{
        
//private variables and functions
         varcomponents=newArray();
        
//initialization
         components.push(newBaseComponent());
        
//create a local copy of application
         varapp=newBaseComponent();
        
//public interface
         app.getComponentCount=function()
        
{
           
returncomponents.length;
        
};
        
app.registerComponent=function(component)
        
{
           
if(typeofcomponent=="object")
           
{
              
components.push(component);
           
}
        
};
        
//return it
         returnapp;
     
}();
     
alert(applicationinstanceofBaseComponent);
     
application.registerComponent(newOtherComponent());
     
alert(application.getComponentCount());  //2