没有名字的函数体:function(){...},它没有名字该怎么找到它呢?
1、如上创建函数的第二种方法,定义一个变量保存存放函数体的地址。那么调用这个变量就相当于调用这个函数了;
var nAdd=function(){
var a=1;
console.log(a);
}
nAdd();//输出1
2、使用()将匿名函数括起来,再添一个();立即执行这个函数体,这里是用匿名函数模拟块级作用域。在函数执行完毕后内部声明的变量就会被释放。模拟了C++里面的块级作用域的效果。
注意:function(){/这里是块级作用域/}():这段代码在运行时会报错,因为JavaScript将function关键字当作一个函数声明的开始,而函数声明后面不能跟(),然而函数表达式后面可以跟(),要将函数声明转化为函数表达式,只要向下面一样加上一对圆括号就可以了:(function(){})();所以用()将匿名函数括起来的实质是将其转化为函数表达式。
alert((function(x,y){return x+y;})(2,3));// "5"
alert((new Function("x","y","return x*y;"))(2,3));// "6"
function outer(){
var a=999;
return a;
}
alert((outer)());//输出999
()的作用:相当于对这个匿名函数实例化了,返回了一个Function对象,只是还是没有名字,需要立即执行(在函数后面添加())。
好处:不用给函数起名字,调用完毕就释放内存,内存消耗不大。
思考一下:下面这段代码应该输出什么
function outer(){
var a=999;
function inner(){
a++;
return a;
}
}
alert((outer)());
答案是:输出undefined,因为执行函数后,没有返回值,所以返回值为undefined,里面的内部函数并没有被执行,只是创建了一个名字为inner函数对象。怎么执行inner函数可以移步:https://blog.csdn.net/lncci/article/details/80179669。所以(f)():就是将函数f执行了一遍。
三、匿名函数的用途:
1、再把函数当成值使用的情况下,可以使用匿名函数。例如:
function createComparisonFunction(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){
return -1;
}elseif{value1>value2}{
return 1;
}else{
return 0;
}
}
}
调用createComparionFunction()传入一个属性,返回一个函数比较两个对象的相关属性的大小。
2、解决闭包的副作用
闭包保存的是整个变量对象,而不是某个特殊的变量,所以闭包只能取得包含函数中任何变量的最后一个值,例如:
function createFunctions(){
var array=[];
for(var i=0;i<5;i++){
array[i]=function(){
return i;
};
}
return array;
}
这个函数会返回一个函数数组,表面上看每个函数都会返回自己的索引值,比如:array[0]();//返回0;array[1]();//返回1,但实际上每个函数都返回5.因为这里闭包访问的是createFunction函数活动对象保存的变量i,每次循环i都在改变,所以最后无论是哪个函数访问到的都是变量i最后一个值。这就是闭包的副作用。
解决方法:用一个匿名函数强制让闭包的行为符合预期。
function createFunctions(){
var array=[];
for(var i=0;i<5;i++){
array[i]=function(num){
return function(){
return num;
}
}(i);
}
return array;
}
测试结果:
在函数中没有直接把闭包赋值给数组。而是定义了一个匿名函数,并将立即执行该匿名函数的结果赋给数组。这里的匿名函数有一个参数num也就是最终的函数要返回的值。在调用每个匿名函数时,我们传人了变量i。由于函数参数是按值传递的,所以城会将变量i的当前值复制给参数num而在这个匿名函数内部,又创建并返回了一个访问num 的闭包。这样来, result 数组中的每个函数都有自己num变量的一个副本,因此就可以返回各自不同的数值了。
3、模拟块级作用域。通常可用在全局作用域中限制向全局作用域中添加过多的变量和函数;
(function(){
var now=new Date();
if(now.getMonth==0&&now.getDate()==1){
alert("happy NewYear!");
}
})();
把上面的代码放进全局作用域中,用来确定哪天是1月1日。如果到了这一天就向用户显示一条祝贺新年的消息,其中变量now是局部变量不需要在全局作用域中去创建它