7.1 递归
- arguments.callee是一个指向正在执行的函数的指针,可以实现函数的递归调用
 
function factorial(num){
         if(num <= 1){
                   return 1;
} else {
         return num * arguments.callee(num - 1);
}
}
var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4)); // output 24
- 在编写递归函数时,使用aguments.callee总比使用函数名更保险;
 
7.2闭包
闭包的特性
- 闭包有三个特性:
 
- 函数嵌套函数;
 - 函数内部可以引用外部的参数和变量(即函数内部定义是函数会将包含函数即外部函数的活动对象添加到它的作用域链中);
 - 参数和变量不会被垃圾回收机制回收;
 
闭包的定义及其优缺点
- 闭包 是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量;
 - 闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露
 - 闭包是javascript语言的一大特点,主要应用闭包场合主要是为了:设计私有的方法和变量。
 - 一般函数执行完毕后,局部活动对象就被销毁,内存中仅仅保存全局作用域。但闭包的情况不同;
 
嵌套函数的闭包
function aa(){
    var a=1;
    return function(){
       alert(a++);
    };
}
var fun = aaa();  
    fun();// 1 执行后 a++,,然后a还在~  
    fun();// 2  
    fun = null;//a被回收!
闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗。
javascript的垃圾回收原理
- 、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
 - 如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
 
使用闭包的好处
- 希望一个变量长期驻扎在内存中
 - 避免全局变量的污染
 - 创建用于访问私有变量的公有方法
 
====全局变量的累加====
var a = 1;
function abc(){
    a++;
    alert(a);
}
abc();              //2
abc();            //3
==局部变量==
function abc(){
        var a = 1;
        a++;
        alert(a);
}
abc();                       //2
abc();                    //2
那么怎么才能做到变量a既是局部变量又可以累加呢?
局部变量的累加
function outer(){
        var x=10;
        return function(){  //函数嵌套函数
            x++;
            alert(x);
        }
}
var y = outer();              //外部函数赋给变量y;
y();                 //y函数调用一次,结果为11,相当于outer()();
y();                //y函数调用第二次,结果为12,实现了累加
模块化代码,减少全局变量的污染
function aa(cout){
    for(var i=0;i<count;i++){
        alert(i);
    }
    alert(i);
}
如上,定义了一个for循环,在有块级作用域的语言中,循环一旦结束,i就会销毁,但在js,变量i、是定义在aa()的活动对象中,在函数内部随处访问到它;
function aa(count){
    (function(){
    //这里是块级作用域
        for(var i=0;i<count;i++){
        alert(i);
        }
    })();
    alert(i);//导致错误
}
如上,我们在for循环外部插入一个私有作用域,在匿名函数中定义的任何变量,都会在执行结束后被销毁;
通过创建私有作用域,每个开发人员既可以使用自己的变量又不必担心搞乱全局作用域;
如:
(function(){
    var now=new Date();
    if(now.getMonth()==0&&now.getDate()==1){
        alert("Happy new year");
    }
    
})();
私有变量:
任何在函数中定义的变量,都可以认为是私有变量。因为在函数外部不能访问这些变量。
把有权访问私有变量和私有函数的公有方法叫特权方法。
function MyObject(){
         //私有变量
         var privateVariable = 10;
         function privateFunction(){
                   return false;
         }
         //特权方法
         this.publicMethod = function(){
                   privateVariable ++;
                   return privateFunction();
         }
}
静态私有变量
(function(){
         var privateVariable = 10;
         function privateFunction(){
                   
         }
         Myobject = function(){               
         }
//公有/特权方法
         Myobject.prototype.publicMethod = function(){
                   privateVariable ++;
                   return privateFunction();
         }
})()
这个模式创建了一个私有作用域,并在其中封装了一个构造函数及相应的方法。