diy1818

Good children, Constantly learning, Constantly growing.

javascript函数表达式

函数声明提升

函数声明的重要特征就是 函数声明提升 在执行代码前会先读取函数声明.这样我们就可以把函数声明放在调用它的语句后面也不会报错.

函数表达式必须在表达式声明后调用,不然会报错.

递归

arguments.callee() 方法是指向一个正在执行的函数的指针.可以用来实现对函数的递归调用.如下:

    function fact(num){
        if(num<=1){
            return 1;
        }else{
            return num * arguments.callee(num-1);
        }
    }

   console.log(fact(4)); // 24

闭包

在一个函数内部创建的另一个函数.

当一个函数被 调用 时,会创建一个执行环境及想就在的作用域链. 然后使用arguments和其他命名参数来初始化函数的活动对象. 但在作用域链中,外部函数的活动对象始终牌第二位...直至作为作用域 链终点的全局执行环境 .

模仿块级作用域

javascript从来不会告诉你是否多次声明 了同一个变量,遇到这种情况,它 只会对后续的声明视而不见(不过,它会执行后续声明中的变量初始化).匿名函数 可以用来模仿块级作用域并避免这个问题.语法如下

     (function(){
        //这里是块级作用域
     })();
 

这种做法,可以减少闭包占用的内存问题.因为没有指向匿名函数的引用,只要函数执行 完毕,就可以立即销毁其作用域链.

私有变量

任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量, 私有变量包括函数的参数\局部变量和在函数内部定义的其他函数.
如果在函数内部创建一个闭包,那么闭包通过 自己的作用域链也可以访问这些变量 .而利用这一点.就可以创建用于访问私有变量的公有方法.

把有权访问私有 变量和私有函数的公有方法称为  特权方法 在对象上创建特权方法的方式.
构造函数中定义特权方法,如下:

    function MyObj(){
        //私有变量各私有函数
        var pri = 10;
        function priFun(){
            return false;
        }
        //特权方法
        this.pubFun = function(){
            pri++;
            return priFun();
        }
    }
    var o = new MyObj();
    o.pubFun();
    console.log(o.pubFun());//false

必须使用构造函数模式来达到特权方法访问和私有变量的目的. 构造函数模式的缺点是针对每个实例都会创建同样一组新方法,而使用静态私有变量 来实现特权方法就可以避免这个问题.