Javascript高级程序设计第二版第七章匿名函数笔记

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

function functionName(){};

这是一个函数声明

在代码执行以前被加载到作用域中

var functionName = function(){};

这是一个函数表达式

在代码执行到那一行时才会有定义

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

7.2 闭包

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

function fn(propertyName){

         return function(object1){

                   var v1 = object1[propertyName]; //访问了外部变量propertyName变量

         }

}

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,过度使用闭包可能会导致内存占用过多。所以建议只是在绝对必要时再考虑使用闭包。

7.2.1 闭包与变量

function createFunctions(){

         var result = [];

         for(var i=0; i<10; i++){

                   result[i] = function(num){

                            return function(){

                                     return num;

                            }

                   }(i);

         }

}

var funcs = createFunctions();

for(var i=0; i<funcs.length; i++){

         document.write(funcs[i] + ‘<br />’); //output 0,1,2,3…9

}

7.2.2 this对象

this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。不过,匿名函数的执行环境具有全局性,因此对象通常指向window.

7.2.3 内存泄漏

如果闭包的作用域中保存着一个HTML元素,那么就意味着该元素无法被销毁。

function assignHandler(){

         var element = document.getElementById(‘someElement’);

         var id = element.id;

         element.onclick = function(){

                   alert(id);

         };

         element = null; //变量设置为null,才能解除对DOM对象的引用,顺利减少引用数,确保正常回收其占用的内存

}

7.3 模仿块级作用域

匿名函数可以用来模仿块级作用域:

(function(){

         //这里是块级作用域

})();

将函数声明包含在一对圆括号中,表示它实际上是一个函数表达式,而紧随其后的另一对圆括号会立即调用这个函数。

相当于:

var someFunction = function(){};

someFunction();

function(){}();

这一段会导致语法错误,因为JavaScriptfunction关键字当作一个函数声明的开始,而函数声明后面不能跟圆括号。然而,函数表达式的后面可以跟圆括号。要将函数声明转换成函数表达式,只要加上一对括号即可。

7.4 私有变量

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

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

function MyObject(){

         //私有变量

         var privateVariable = 10;

         function privateFunction(){

                   return false;

         }

         //特权方法

         this.publicMethod = function(){

                   privateVariable ++;

                   return privateFunction();

         }

}

7.4.1 静态私有变量

(function(){

         var privateVariable = 10;

         function privateFunction(){

                  

         }

         Myobject = function(){              

         }

//公有/特权方法

         Myobject.prototype.publicMethod = function(){

                   privateVariable ++;

                   return privateFunction();

         }

})()

这个模式创建了一个私有作用域,并在其中封装了一个构造函数及相应的方法。

7.4.2 模块模式

单例创建私有变量和特权方法。所谓单例就是只有一个实例的对象。简单的语法如下:

var singleton = {

         name: value,

         method: function(){

//这里是方法

}

}

还可以添加私有变量和特权方法

var singleton = function(){

         //私有变量和私有函数

         var privateVariable = 10;

         function privateFunction(){}

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

         return {

         publicProperty: true,

         publicMethod: function(){

         privateVariable++;

         return privateFunction();

}

}

}

这个模式返回了一个匿名函数,在函数内部,定义私有变量和函数,然后将一个对象字面量作为函数的值返回。返回的对象字面量中只包含可以公开的属性和方法。

7.4.3 增强的模块模式

var singleton = function(){

         //私有变量和私有函数

         var privateVariable = 10;

         function privateFunction(){

         return false;

}

//创建对象

var object = new CustomType();

//添加特权/仅有属性和方法

object.publicProperty = true;

object.publicMethod = function(){

         privateVariable++;

         return privateFunction();

};

return object;

}

原文地址:https://www.cnblogs.com/jikey/p/1802068.html