高程3总结#第7章函数表达式

函数表达式

递归

  • 递归函数是在一个函数经过名字调用自身的状况下构成的javascript

    function factrial(num){
      if(num<=1){
        return 1;
      }else {
        return num*factrial(num-1);
      }
    }
  • argument.callee是一个指向正在执行的函数的指针,所以能够用它来实现对函数的递归调用java

    function factorial(num){
      if(num<=1){
        return 1;
      }else {
        return num*argument.callee(num-1)
      }
    }
  • 严格模式下不能经过脚本访问argument.callee,访问这个属性会致使错误,不过可使用命名函数表达式类达成相同的结果闭包

    var factorial=(function f(num){
      if(num<=1){
        return 1;
      }else {
        return num*f(num-1);
      }
    })

闭包

  • 闭包是指有权访问另外一个函数做用域中的变量的函数app

    function compare(value1,value2){
      if(value1<value2){
        return -1;
      }else if(value1>value2){
        return 1;
      }else {
        return 0;
      }
    }
    var result=compare(5,10)

    图片描述

    //建立函数
    var compareNames = createComparisonFunction("name");
    //调用函数
    var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
    //解除对匿名函数的引用(以便释放内存)
    compareNames = null;

    图片描述

闭包与变量

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

    function creatFunctions(){
      var result=new Array();
      for(var i=0;i<10;i++){
        result[i]=function(){
          return i;
        };
      };
      return result;
    }
  • 经过匿名函数强制让闭包的行为符合预期this

    function createFuntion(){
      var result=new Array();
      for(var i=0;i<10;i++){
        result[i]=function(num){
          return function(){
            return num;
          };
        }(i);
      }
      return result;
    }

关于this对象

  • 匿名函数的执行环境具备全局性,所以其this对象一般指向window
  • 把外部做用域中的this对象保存在一个闭包可以访问到的变量里,就能够了让闭包访问这个对象了spa

    var name="The Window";
    var object={
      name:"My Object",
      getNameFunc:function(){
        var that=this;
        return function(){
          return that.name
        };
      }
    };
    alert(object.getNameFunc()());//"My Object"
  • 定义米明函数以前,咱们把this对象赋值给了一个名叫that的变量,而在定义了这个闭包以后,闭包也能够访问这个变量,所以它是咱们在包含函数中特地声明的一个变量,即便在函数返回以后,that也仍然引用这object

内存泄漏

  • 若是闭包做用域中保存着一个HTML元素,那么久意味着该元素将没法被销毁prototype

    function assignHandler(){
      var element=docunemt.getElementById("someElement");
      element.onclick=function(){
        alert(element.id)
      }
    }
  • 以上代码段中的element占用的内存永远不会被回收指针

    function assignHandler(){
      var element=document.getElementById("someElement");
      var id=element.id;
      element.onclick=function(){
        alert(id);
      }
      element=null;
    }

模仿块级做用域

function outputNumbers(count){
  for(var i=0;i<count;i++){
    alert(i);
  }
  var i;//从新声明变量
  alert(i);//计数
}
  • JavaScript历来不会告诉你是否屡次声明了同一个变量,遇到这种状况,只会对后续的声明视而不见,不过会执行后续声明中的变量初始化。匿名函数能够用来模仿块级做用域来避免这个问题code

    (function(){
      //这里是块级做用域
    })()
  • 代码定义并当即调用了一个匿名函数,将函数声明包含在一对圆括号中,表示它其实是一个函数表达式,而紧随其后的另外一对圆括号会当即调用这个函数。

    function outputNumbers(count){
      (function(){
        for(var i=0;i<count;i++){
          alert(i)
        }
      })();
      alert(i);//致使一个错误
    }
  • 这种技术常常在全局做用域中被用在函数外部,从而限制向全局做用域中添加过多的变量和函数。通常来讲,咱们应该尽可能少向全局做用域中添加变量和函数

私有变量

  • JavaScript中灭有私有成员的概念,因此对象属性都是共有的。任何在函数中定义的变量,均可以认为是私有变量,由于不能在函数的外部访问这些变量,私有变量包括函数的参数、局部变量和在函数内部定义的其余函数。
  • 若是在函数内部建立一个闭包,那么闭包经过本身的做用域链也能够访问函数内的变量

静态私有变量

(funciton(){
  //私有变量和私有函数
  var privateVariable=10;
  function privateFunction(){
    return false;
  }
  //构造函数
  MyObject=function(){}
  //公有/特权方法
  MyObject.prototype.publicMethod=function(){
    privateVariable++;
    return privateFunciton();
  }
})();
  • 在私有做用域中,首先定义了私有变量和私有函数,而后又定义了构造函数及其公有方法

模块模式

  • 模块模式是为单例建立私有变量和特权方法。单例指的就是只有一个实例的对象。按照惯例,JavaScript是以字面量的方式来建立单例对象的

    var singleton={
      name:value,
      method:function(){
        //这里是代码方法
      }
    }
  • 模块模式经过为单例添加私有变量和特权的方法可以使其获得加强

    var singleton=function(){
      //私有变量和私有函数
      var privateVariable=10;
      funciton privateFunction(){
        return false;
      }
      //特权/公有方法和属性
      return {
        publicProperty:true,
        publicMethod:function(){
          privateVariable++;
          return privateFunction();
        }
      };
    }();

加强的模块模式

var application = function(){
//私有变量和函数
var components = new Array();
//初始化
components.push(new BaseComponent());
//建立 application 的一个局部副本
var app = new BaseComponent();
//公共接口
app.getComponentCount = function(){
  return components.length;
};
app.registerComponent = function(component){
  if (typeof component == "object"){
    components.push(component);
  }
};
//返回这个副本/
return app;
}();
相关文章
相关标签/搜索