javascript匿名函数
javascript的匿名函数看了一遍感觉有点模糊,可能是跟其他oo语言的区别而导致的,现在我就来详细的整理一下,方便自己和大家的理解。
匿名函数就是没有名字的函数,又称lamda函数,一般用在一个函数中去实现某种功能或者直接赋给一个变量如:var person=function{};我就来说一下匿名函数的具体用途吧。
一.闭包的概念:
1.闭包是指有权访问另一个函数中变量的函数。例如,在一个函数内部创建一个函数,这个和其他语言差不多,这个内部函数就可以访问包含它的函数中的变量。
看下面代码:
function createComparisionFunction(propertyName){ return function(object1,object2){ var value1=object1[propertyName]; var value2=object2[propertyName]; if(value1<value2) return -1; if(value1==value2) return 0; if(value1>value2) return 1; } }
红色标记的两行就访问了外部变量propertyName,因为这个内部函数的作用域包括了函数createComparisionFunction的作用域。我觉得这一点不难理解,我也就不多介绍了,主要是关于作用域的问题。另外,我们在执行完一次createComparisionFunction后,如
var compareName=createComparisionFunction("name");//声明函数
var result=compareName({name:"wk"},{name:"gyy"});//调用内部匿名函数
compareName=null;//解除对内部函数引用,释放内存,否则会一直占据内存。
下图是上面三行代码执行过程中域链:
2.闭包与变量:作用域链的这种机制的副作用就是让闭包只能取得包含函数中的变量的最后一个值,闭包保存的是整个变量对象,而不是某个特殊的变量,看下面实例。
function tempFunction(){ var result=new Array(); for(var i=0;i<10;i++){ result[i]= function(){ return i; }; } return result; } var funcs = tempFunction(); for(var i=0;i<funcs.length;i++){ alert(funcs[i]()); }
上段代码,tempFunction返回一个函数组,当执行完红色那行代码时,内部函数中的i已经变为10,所以这个结果就是一直打出10了。
3.关于this对象:
第一点也是跟作用域有关,上面说了内部函数的作用域会包括包含函数,所以使用this的时候,结果并不是指这个包含函数(更外一点)。
var name="window"; var testObeject={ name: "object", getObjectFunction:function(){ return function(){ return this.name; }; } }; alert(testObeject.getObjectFunction()());
大家看完这段代码能够迅速反应出结果是window 就可以了,注意我红色区域,理解一下。
二.模仿块级作用域
javascript中没有块状作用域,以前习惯for(int i=0;i<k;i++)和if(...) 这里面定义的变量的作用域其实是在整个函数中的。我们可以通过使用匿名函数来模仿构造一个块状作用域。
注:有些人以为大不了在循环外面重新声明一下var i,这种方法是错误的,因为javascript从不告诉你是否多次声明,如果遇到多次声明,对第一次以后的声明它都视而不见。
用作块状作用域的匿名函数语法如下:
(function(){
//块状作用域
})();
这里面就不用实例了,大家可以写一个for循环,然后在匿名函数外面alert(i)是否报错。
三.私有变量
java中没有私有成员的概念,所有对象属性都是公有的,不过倒是有一个私有变量的概念。任何在函数中定义的变量都是私有变量,包括函数参数、局部变量和在函数中定义的其他函数。
特权函数:私有函数只能在函数内部使用,不能在函数外部使用,我们把可以访问私有变量和私有方法的公有方法称为特权函数。
第一种创建特权函数方法:在构造函数中定义特权函数(可以参照我的另一篇文章--javascript对象的创建)
function MyObeject(){ var privateVariable=1; function privateMethod(){ return false; } this.publicMethod=function(){ privateVariable++; return privateMethod(); } }
这个例子中,在实例化对象后,除了publicMethod方法可以访问两个私有变量,其他都不能访问了。使用这种方法同样拥有构造函数法创建对象的缺陷:每个实例都会创建一组新方法。
第二种是静态私有变量:通过在私有作用域中定义私有变量和方法。
(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("wangke"); alert(person.getName()); person.setName("Greg"); alert(person.getName()); var person2=new Person("gyy"); alert(person2.getName()); alert(person.getName());
输出结果依次是:wangke Greg gyy gyy 大家对照代码好好理解一下。另外在javascript中对于没有声明的对象一律按照全局变量对待,所以这里面的Person是个全局变量。
关于匿名函数的其他一些东西我就不写了,这里面主要也就是讲了匿名函数的一些应用吧,自己敲代码,可以尝试各种修改,会出现各种有趣的结果。