天天看点

函数表达式-JS高程函数表达式

函数表达式

  1. 定义函数的方式有两种:
    1. 函数声明
    sayHi();  
    function sayHi() {  
        alert('hi');  
    }
               
    1. 函数表达式
    var functionName = function(a,b,c){}
               
  2. 注意
    1. 匿名函数
    2. 使用前必须先赋值
//错误代码  
    sayHi();  
    var sayHi = function() {  
        alert('hi');  
    }  
    //另一个例子  
    var sayHi;  //如果不赋值在js中属于无效语法  
    if(condition) {  
    sayHi = function() { alert('hi');}  
    }else {  
    sayHi = function() { alert('aha');}  
    }
           

递归

  1. 问题1
    var diguiA = digui;  
    digui = null;  
    alert(diguiA(4));
               
  2. arguments.callee

    是一个指向正在执行的函数的指针,以此来替代函数名,调用函数。

  3. 问题2

    严格模式下,访问这个属性会产生错误

  4. 解决(命名函数表达式)
    var digui = (function d(num) {  
        if (num <= 1) {  
        return  1;  
        } else {  
        return num * f(num-1);  
        }  
    })
               

闭包

有权访问另一个函数作用域中的变量的函数。

创建闭包的常用方式,就是在一个函数内部创建另一个函数。

function out(outX) {  
    return function (object1,object2) {  
        var a = object[outX]  
        var b = object[outX]  
        //函数代码  
    }
}
           
  1. 作用域链
    1. 本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。
    2. 在创建A()函数的时候,会创建一个预先包含全局变量的作用域链,这个作用域链被包含在内部的[[Scope]]属性中。当调用A()函数时,会为函数创建一个执行环境,然后通过啊复制函数的[[Scope]]属性中的对象构建起执行环境中的作用域链。
    3. 函数执行完后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。
    4. !!!闭包与此不同!!!另一个函数内部定义的函数回京包含函数(即外部函数)的活动对象添加到他的作用域链中。换而言之,匿名函数可以访问在out()中定义的所有变量。
  2. 副作用

    闭包只能取得包含函数中任何变量的最后一个值

    function A() {  
        var result = new Array();  
        for(var i = 0;i < 10;i++) {  
            result[i] = function(){  
                return i;  
            };  
        }  
    } 
               
    //解决
    function A() {  
        var result = new Array();  
        for(var i = 0;i < 10;i++) {  
            result[i] = function(num){  
                return function() {  
                    return num;  
                }
            };  
        }  
    }
               
  3. this对象

    匿名函数的执行环境具有全局性,因此其this对象通常指向window。

  4. 内存泄漏

    闭包的作用链中包含html元素

模仿块级作用域

  1. JS没有块级作用域的概念。JS不会告诉你是否多次声明了同一个变量,他会对后续的声明视而不见但会执行初始化。
  2. 这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中的所有变量。
    function A(count) {
        for(var i = 0;i < count;i++) {
            alert(i);
        }
        alert(i);
    }
               
  3. 实现
    (function() {
        //这里是块级作用域
    })();
    
    var A = function () {
        //这里是块级作用域
    }
    A();
               

私有变量

  • JS中没有私有成员的概念,所有对象属性都是共有的。
  • 私有变量:定义在函数中的变量。
  • 特权方法:有权访问私有变量和私有函数的公有方法。
  1. 静态私有变量

    在一个私有作用域下,定义私有变量或函数。

  2. 模块模式
    1. 为只有一个实例的对象创建私有变量和特权方法
    2. 如果必须创建一个对象并以某些数据对其进行分初始化,同时还要公开一些能够访问这些私有数据的方法,那就可以使用模块模式。
      var A = {
          name : value,
          method : function () {
              //这里是方法的代码
          }
      }
                 
  3. 增强的模块模式

    在返回对象之前加入对其增强的代码。比如,能够访问私有变量的公有方法。

继续阅读