《javascript高级程序设计2》学习笔记7 匿名函数

匿名函数就是没有名字的函数,有时候也称为拉姆达(lambda)函数。

//函数声明
function functionName(){

}
//函数表达式
var functionName = function(arg0,arg1,arg2){

}
/*
 *区别:
 *1函数声明会在代码执行以前被加载到作用域  会指定一个名字
 *2函数表达式在代码执行到那一行的时候才会有定义   创建一个匿名函数。赋给变量
 */

 

7.1 递归

 递归函数是在一个函数通过名字调用自身的情况下构成的。

 arguments.callee是一个指向正在执行的函数的指针,可以实现函数的递归调用

 

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

            var anotherFactorial = factorial;
            factorial = null;
            alert(anotherFactorial(4));  //error!
          //在编写递归函数时,用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));  //24

 

7.2 闭包

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

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

 

function f1(){
  var n = 999;
  nAdd = function(){
    n+=1;
  }
  function f2(){
    alert(n);
  }
  return f2;
}

var result = f1();
result();
nAdd();
result();


var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());
 7.2.1闭包与变量

闭包所保存的是整个变量对象,不是某个特殊的变量。

 7.2.2 this对象
this对象是在运行时基于函数的执行环境绑定的。
在全局函数中,this等于window。
当函数被作为某个对象的方法调用时,this等于那个对象。
匿名函数的执行环境具有全局性,this指window
 7.2.3内存泄露
如果闭包的作用域链中保存着一个html元素,该元素无法被销毁。必须设为null。
function assignHandler(){
	var element = document.getElementById("elementId");
	var id = element.id;//element.id保存在变量id中

	element.onclick = function(){
		alert(id);	//在闭包中引用该变量消除循环引用
	};
	element = nul;	//将element设为null
}
 

7.3 模仿块级作用域

匿名函数可以用来模仿块级作用域(私有作用域)

 

(funciton(){
     //这里是块级作用域
})();
 无论在什么地方,只要临时需要一些变量,就可以使用私有作用域。

 

通过创建私有作用域,每个开发人员既可以使用自己的变量,又不必担心搞乱全局作用域。

这种做法可以减少闭包占用的内存问题。

 

7.4 私有变量

js没有私有成员的概念,所有对象都是公有的。

任何在函数中定义的变量,都可以认为是私有变量,因为不能再函数的外部访问这些变量。

私有变量包括函数的参数,局部变量和在函数中定义的其他函数。

 

特权方法: 有权访问私有变量和私有函数的公有方法。

2种创建特权方法的方式。

1 在构造函数中定义特权方法。

 

function Person(name){
                this.getName = function(){
                    return name;
                };

                this.setName = function(value){
                    name = value;
                };
}

 var person = new Person("flyer");
 alert(person.getName());
 person.setName("bird");
 alert(person.getName());
 缺点:必须使用构造函数来达到目的。构造函数模式缺点是针对每个实例都会创建同样一组新方法。使用静态私有变量可以避免。

 

 7.4.1 静态私有变量

 

            (function(){
            
                var name = "";
                
                Person = function(value){                
                    name = value;                
                };
                
                Person.prototype.getName = function(){
                    return name;
                };
                
                Person.prototype.setName = function (value){
                    name = value;
                };
            })();
            
            var person = new Person("flyer");
            alert(person.getName());   
            person.setName("bird");
            alert(person.getName());   
 

 

7.4.2 模块模式

道格拉斯所说的模块模式是为单例创建私有变量和特权方法,所为单例,指只有一个实例的对象。

javascript是以对象字面量来创建单例的。

 

var singleton(){
   name: value,
   method: function(){
      //这里是方法的代码
   }

}
 模块模式通过为单例添加私有变量和特权方法使其增强:
var singleton = function(){    //返回对象的匿名函数。

         //私有变量和私有函数

         var privateVariable = 10;

         function privateFunction(){
          return false; 
         }

         //特权/公有方法和属性

         return {
           publicProperty: true,

          publicMethod: function(){
              privateVariable++;
               return privateFunction();

           }
        };

}();

 

7.4.3 增强的模块模式

适合那些单例必须是某种类型的实例,同事还必须添加某些属性和方法对其加以增强的情况。

 

        
            function BaseComponent(){
            }
            
            function OtherComponent(){
            }
        
            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;
            }();

            alert(application instanceof BaseComponent);
            application.registerComponent(new OtherComponent());
            alert(application.getComponentCount());  //2

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值