匿名函数私有化问题

模仿块级作用域
javascript没有块级作用域的概念

function box(count){
    for(var i=0;i<count;i++){}    //看做块级作用域
    var i;                        //就算重新声明,也不会影响之前声明初始化的数据
    alert(i)                      //块级以外还可以访问到
}

以上例子,说明了Javsscript没有块级作用域,if(){},for(){}等没有作用域,如果有,出了这个范围i就应该被销毁了。就算重新声明同一个变量也不会改变它的值。

Javascript不会提醒你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见(付过初始化了,当然还是会执行的)。使用模仿块级作用域可避免这个问题。

//模仿块级作用域(私有作用域)
(function(){
    //这里是块级作用域
})();

//使用块级作用域(私有作用域)改写
function box(count){
    (function(){             //包含自我执行的匿名函数,就可以实现私有作用域
        for(var i=0;i<count;i++){}
    })();                    //出了这个私有作用域,变量立即被销毁
    alert(i)                         //报错,无法访问
}

使用了块级作用域(私有作用域)后,匿名函数中定义的任何变量,都会在执行结束时被销毁。这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。一般来说,我们都应该尽可能少向全局作用域中添加变量和函数。在大型项目中,多人开发的时候,过多的全局变量和函数很容易导致命名冲突,引起灾难性的后果。如果采用块级作用域(私有作用域),每个开发者既可以使用自己的变量,又不比担心搞乱全局作用域

(function(){
    //这里就是全局的私有作用域
    var box=[1,2,3,4];
    alert(box);
})

在全局作用域中使用块级作用域可以减少闭包占用的内存问题,因为没有指向匿名函数的引用。只有函数执行完毕,就可以立即销毁其作用域链了。

私有变量
Javascript没有私有属性的概念;所有的对象属性都是共有的。不过,却又一个私有变量的概念。任何在函数中定义的变量,都可以认为是私有变量,因为不能再函数的外部访问这些变量。

function box(){
    var age=100;                //私有变量,外部无法访问
}

而通过函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问这些变量,而利用这一点,可以创建用于访问私有变量的共有方法。

function Box(){
    var age=100;                //私有变量
    function fun(){
        return '运行中。。。'     //私有函数
    }
    this.get=function(){        //对外可见的公共接口,特权方法
        return age+run();
    }
}
var box=new Box();
alert(box.get());

还可以通过构造方法传参来访问私有变量。

function Person(value){
    var user=value;
    this.getUser=function(){
        return user;
    }
    this.setUser=function(value){
        user=value;
    }
}

但是对象的方法,在多次调用的时候,会创建多次。可以使用静态私有变量来避免这个问题。

静态私有变量
通过块级作用域(私有作用域)中定义私有变量或函数,同样可以创建对外公共的特权方法。

(function(){
    var age=100;
    function run(){
        return '运行中。。。';
    }
    Box=function(){};            //构造方法
    Box.prototype.go=function(){   //原型方法
        return age + run();
    };
})();

上面的对象声明,采用的是Box=function(){}而不是function Box(){},因为如果用后面这种,就变成私有函数了,无法在全局访问到,所以使用了前面这种。

(function(){
    var user='';
    Person=function(value){    //构造函数,在函数里写构造函数不支持,因为私有作用域里的函数,外部无法访问到。
        user=value;
        /*this.getUser=function(){
            return user;
        }*/
    };
    Person.prototype.getUser=function(){
        return user;
    };
    Person.prototype.setUser=function(value){
        user=value;
    };
})();

使用了prototype导致方法共享了,而user也变成静态属性了。(所谓静态属性,即共享于不同对象中的属性)。

模块模式
之前采用的都是构造函数的方法来创建私有变量和特权方法。那么对象字面量方式就采用模块模式来创建。

var box={                    //字面量对象,也是单例对象
    age:100,                 //这是共有属性,也要改成私有
    run:function(){          //这是共有函数,将要改成私有
        return '运行中。。。'
    }
}

私有化变量和函数

var box=function(){               
     var user='Lee';
     function run(){
         return '运行中。。。'
     }
     return {
         publicGo:function(){  //对外公共接口的特权方法
             return user+run;
         }
     }
}();

相当于
var box=function(){               
     var user='Lee';
     function run(){
         return '运行中。。。'
     }
     var obj= {
         publicGo:function(){  //对外公共接口的特权方法
             return user+run;
         }
     }
     return obj;
}();

字面量的对象声明,其实在设计模式中可以看作是一种单例模式,所谓单例模式,就是永远保持对象的一个实例。
增强的模块模式,这种模式适合返回自定义对象,也就是构造函数。

function Desk(){};
var box=function(){
    var age=100;
    function run(){
        return '运行中。。。';
    }
    var desk=new Desk();           //可以实例化特定的对象
    desk.go=function(){
        retrun age+run();
    }
    return desk;
}();
alert(box.go());
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值