私有变量和方法
JavaScript中想要在构造函数中创建私有的变量和方法就必须利用闭包(关于闭包可以访问我的博客:闭包理解),现在通过代码来说明如何创建私有变量及其原理。
function Person(){
var name; //私有变量
var say=function(){ //私有方法
alert('hello');
}
this.getName=function () { //私有变量的外部访问方法
return name;
}
this.setName=function (newname) { //私有变量的外部访问方法
name=newname;
}
}
var p1=new Person();
p1.setName("lisi");
console.log(p1.getName()); //lisi
在上面的代码中,name变量是Person函数的作用域下的局部变量只能在Person函数内部访问,但是this.getName和this.setName通过闭包的方式保存了Person函数的作用域对象,即getName和setName通过作用域链引用全局作用对象和Person作用域对象以及自身作用域对象,在Person作用域对象中包含name变量,而Person中的this引用Person的实例所有可以通过getName和setName这个两个外部方法来访问Person中的私有变量name
作用域链如图:
静态变量
静态变量类似于java中的静态变量,java中的静态变量是属于类的变量,即所用对象共享静态变量,通过一下代码来实现JavaScript中的静态变量
(function () {
var name;
Person=function(){};//没有使用var定义变量,那么默认作用域是window
Person.prototype.getName=function () {
return name;
}
Person.prototype.setName=function (newname) {
name=newname;
}
})();
var p1=new Person();
var p2=new Person();
p1.setName("lisi");
console.log(p1.getName()); //lisi
console.log(p2.getName()); //lisi
以上代码通过一个匿名函数实现块级作用域,在块级作用域中变量name只能在该作用域中访问,同样的通过闭包(作用域链)的方式实现getName和setName来访问name,而getName和setName又是原型对象的方法所以它们成为了Person实例的共享方法。
块级模式
所谓块级模式就是给单例对象添加私有私有变量和特权方法(访问私有变量的方法)
JavaScript中的单例通过对象字面量的形式产生:
var singleton = {
name : value,
method : function () {
//这里是方法的代码
}
};
模块模式通过为单例添加私有变量和特权方法能够使其得到增强
var application = function(){
//私有变量和函数
var components = new Array();
//初始化插件
components.push(new BaseComponent());
//公共
return {
getComponentCount : function(){
return components.length; //获取插件数量
},
registerComponent : function(component){ //注册插件
if (typeof component == "object"){
components.push(component);
}
}
};
}();
上面通过一个插件应用来解释模块模式。
增强模块模式
有人进一步改进了模块模式,即在返回对象之前加入对其增强的代码。这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和(或)方法对其加以增强的情况。来看下面的例子。var singleton = function(){
//私有变量和私有函数
var privateVariable = 10;
function privateFunction(){
return false;
}
//创建对象
var object = new CustomType(); //返回的是特定类型的实例,这就是模块模式的增强
//添加特权/公有属性和方法
object.publicProperty = true;
object.publicMethod = function(){
privateVariable++;
return privateFunction();
};
//返回这个对象
return object;
}();