javaScript 利用闭包模拟对象的私有属性

JavaScript缺少块级作用域,没有private修饰符,但它具有函数作用域。作用域的好处是内部函数可以访问它们的外部函数的参数和变量(除了this和argument。内部中的函数中的this指向全局对象,argument指向内部函数的函数参数)。我们可以利用这种属性来模拟面向对象中的私有属性。

var myObject=function(value){
        var value=value || 0;
        
        return{
                increment:function(num){
                        value+=typeof num==='number' ? num : 0;
                },
                setValue:function(num){
                        value = typeof num==='number' ? num : value;
                },
                getValue:function(){
                        return value;
                }
        }
}(10)

//alert(myObject.getValue());  //10
myObject.setValue(20);
//alert(myObject.getValue());  //20

myObject.increment(5);
alert(myObject.getValue());  //25

如上例中,myObjeact是匿名函数执行后返回的对象。匿名函数中变量value对于匿名函数外部来说是不可访问的,但对于其内部的函数,是可以访问的,匿名函数执行结束,由于变量value仍被返回的myObject对象所存取,故value所占据的内存并没有被销毁。此时,内部的变量value就如同myObject对象的私有变量一样。

var myObject=function(value){
        var name='MyObject';
        return{
                increment:function(num){
                        value+=typeof num==='number' ? num : 0;
                },
                setValue:function(num){
                        value = typeof num==='number' ? num : value;
                },
                getValue:function(){
                        //alert(this);
                        return value;
                },
                getName:function(){
                        return name;
                },
                setName:function(nameStr){
                        name=nameStr;
                },
                toString:function(){
                        return '[Object:'+name+']';
                }
        }
}


var obj=myObject(5);
obj.increment(6);   
//alert(obj.getValue());  // 11
//alert(obj);   //[Object:MyObject]
obj.setName('temp object 01');
alert(obj)   //[Object:temp object 01]