匿名函数

    一、函数本质:一个 封装代码段 的Function对象,函数名只是一个引用函数对象的变量
    函数的创建: 3种方法
      1. 声明: function 函数名(形参列表){函数体; return 返回值;}
         function fun和var fun都是声明/创建一个变量的意思,
             何时使用参数: 只要函数步骤中必须某些数据才能正常执行时,就要定义参数。
             何时使用返回值: 如果函数的调用者需要函数的执行结果时,函数就必须返回值。
        function声明的函数可被声明提前: 在程序开始执行前,会将var声明的变量和function声明的函数(注意是整个函数)提前到*当前作用域*的顶部集中创建。但赋值留在原地!
      2. 函数表达式:
       var  函数名=function(参数列表){函数体; return 返回值;};
       函数名仅是一个普通的变量,函数定义其实是一个对象,函数名中仅保存了函数对象的地址——引用,

     3. 用new:
       var 函数名=new Function("参数1","参数2",...,"函数体; return 返回值")//所有形参必须放在“”中!
       所有函数都是一个Function对象,所以可以直接用浏览器内部的内置对象:Function,实例化一个函数对象。
  二、匿名函数:

        没有名字的函数体: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是局部变量不需要在全局作用域中去创建它

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值