JavaScript(8):即时函数

本文详细介绍了JavaScript中立即执行函数IIFE的概念、使用方式,包括无参数和带参数的实例,并探讨了其与闭包、表达式求值和执行操作符的关系。通过实例演示了如何利用IIFE进行变量作用域控制和模块化开发。
摘要由CSDN通过智能技术生成

  在JavaScript中定义一个函数后,声明一个函数并马上执行(调用)这个函数,这样的函数就是立即执行函数(Immediately-Invoked Function Expression 即IIFE),也称为即时函数(Immediately Function)。
  典型样式:

(function(形参){
//执行语句
//......
})(实参)

  也可以是:

(function (形参) {
//执行语句
//......
}(实参))

  推荐是第一种的写法,因为清楚明了,不容易产生歧义。
  有的习惯性在前面加;,比如;(function(){})();,这个是为了避免错误的习惯性写法(前面的语句最后没有加;)。
  如果在函数内没有对外变量的引用,也即没有闭包存在,那么这个函数执行完就作为垃圾回收了。
  多数情况下,我们应用都是没有实参和形参的。
  这里有一些的例子:

	(function func(){ console.log('B')})();//输出B
	console.log(!!function func(){ return 'C'; }());//输出true
	console.log(!(function(){ return true})());//输出false
	console.log(1 + function func(){ return 1; }());//输出2
	-(function func(){ console.log('D');})();//输出D

  在JavaScript语言当中要了解立即执行函数,先了解()的作用。
  ()可以是求值。
  那么圆括号里面的就是表达式。
  比如,可以写:
  a=(1+2);
  console.log(a);//输出3
  但是写成a=(1+2;)则报错,因为括号里面的是语句不是表达式。
  又例如:
  function a(){console.log('1')}();
  这个是报错的,因为JavaScript解释器遇到以function开头的都会以语句来解释。
  (function a(){console.log('1')}());
  这个则可以正确输出,因为以()包裹,则JavaScript解释器会认为里面的是可以执行的表达式。
  ()也可以是执行操作符。
  我的理解就是{}与执行()一一对应,想着是剥洋葱,{}就是封一层洋葱皮,而()则是剥一层洋葱皮。

	var K=function a(){
		return function b(){
			return function c(){
				return function d(){
					return 'JavaScript';
				}
			}
		}
	};
	
	console.log(K()()()());	//输出JavaScript

  在JavaScript语言当中,()也是一个很神奇的存在,试看下面的代码,只是()的位置不一样导致结果也是不一样的。

	var a=(  function(){
		var count=0;
		return function (){
				count=count+1;
				return count;
		}
	})();
	
	console.log(typeof a);	//输出function
	console.log(a());//输出1
	console.log(a());//输出2
	console.log(a());//输出3

  上面的这个例子利用结合闭包来实现特定的效果。
  下面只是改变()的位置:

	var a=(  function(){
		var count=0;
		return function (){
				count=count+1;
				return count;
		}
	})()();
	
	console.log(typeof a);//输出number
	console.log(a);//输出1
	console.log(a);//输出1
	console.log(a);//输出1

  又或者写成下面的样式:

	var a=(  function(){
		var count=0;
		return function (){
				count=count+1;
				return count;
		}
	});
	
	console.log(typeof a);//输出function
	console.log(a()());//输出1
	console.log(a()());//输出1
	console.log(a()());//输出1

  下面是一个简单的计数功能的例子。

;(function (){
	var count=0;
	function add(){//增加计数
		count=count+1;
		return count;
	}
	function reduce(){//减少计数
		count=count-1;
		return count;
	}
	window.JS=function(){ return { add:add,reduce:reduce } }
}
)();
console.log(window.JS().add());//输出1
console.log(window.JS().add());//输出2
console.log(window.JS().add());//输出3

console.log(window.JS().reduce());//输出2
console.log(window.JS().reduce());//输出1

  下面是一道面试题,也是即时函数与闭包结合比较典型的试题:

	for(var i=0;i<5;i++){
		setTimeout( function(){
			i=i+1;
			console.log(i);
		},5000);
	};
  console.log('i:'+i);

  上面的代码段输出是什么?
  setTimeout(表达式,延时时间),意思是在载入后,在延迟时间后执行一次表达式。
  setInterval(表达式,交互时间),意思是在载入后,每隔交互时间就执行一次表达式。
  实际输出:

  如果要输出1、2、3、4、5,则应该改写代码:

	for(var i=0;i<5;i++){
		(function(x){
			setTimeout( function(){
				x=x+1;
				console.log(x);
			},5000)			
		})(i);
	}
	console.log('i:'+i);

   实际输出:

  上面的这道题目和下面的类似:

	function func(){
		for(var i=0,arr=[];i<5;i++){
			arr[i]=function(){ console.log(i) }
		}
		return arr;
	}
	
	var funs=func();
	funs[0]();//输出5
	funs[1]();//输出5
	funs[2]();//输出5
	funs[3]();//输出5
	funs[4]();//输出5

  而要想输出0、1、2、3、4,则可以使用即时函数来完成:

	function func(){
		for(var i=0,arr=[];i<5;i++){
			(function(i){ arr[i]=function(){ console.log(i) }} )(i)
		}
		return arr;
	}
	
	var funs=func();
	funs[0]();//输出0
	funs[1]();//输出1
	funs[2]();//输出2
	funs[3]();//输出3
	funs[4]();//输出4

  因为是作用域的问题,在ES6中可以使用let赋值来解决就简单多了:

	function func(){
		let arr=[];
		for(let i=0;i<5;i++){
			arr[i]=function(){ console.log(i) }
		}
		return arr;
	}
	
	var funs=func();
	funs[0]();//输出0
	funs[1]();//输出1
	funs[2]();//输出2
	funs[3]();//输出3
	funs[4]();//输出4

  在实际的应用中,我们常见即时函数的应用,比如事件挂载与绑定、初始化应用等等,即时函数经常与闭包联系在一起使用,比如在变量声明与引用、模块化开发等方面。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值