自动执行函数/立即调用的函数表达式

一般调用函数的写法:

var someFunction=function(){
alert("立即调用的函数表达式")
};
someFunction();

函数表达式后面可以跟圆括号,上面写法还可改写成:

var someFunction=function(){
alert("立即调用的函数表达式")
}();

函数声明后面不能跟圆括号,就是说下面的写法是错误的:

function(){}();

上面也有提到函数表达式后面可以跟圆括号,以实现立即调用/执行的效果,函数声明转换成函数表达式方法:

赞助商链接


// 下面2个括弧()都会立即执行
(function () { /* code */ } ());
(function () { /* code */ })();

括号做的事情都是一样的,消除歧义才是它真正的工作,而不是把函数作为一个整体,所以无论括号括在声明上还是把整个函数都括在里面,都是合法有效的。
注意这两种写法:匿名函数上面的写法都存在前后文;问题,所以需要注意的是匿名函数在压缩工具打包压缩后会出现上下文错误合并()的问题,例如第二种写法。如果下面的代码,未压缩之前是正常的,压缩后就不正常了,所以要严格上下文的;问题,而第一种就不会出现类似问题

//var a = function(){}
var a="bbb"
(function(){
	alert(1);
})();

上述代码会报"string is not a function"错误,若变量a是一函数,则会报"undefined is not a function",这是因为a变量或a函数会把他后面的匿名函数作为参数传入a中,这就很好的解释了为什么报前面提到的错误,这也很好地解释了为什么有人习惯在匿名函数之前添加;了,就是为了防止上文没有严格遵循javascript语法,漏掉;的问题。
而使用第1种写法就不会报错,如:

//var a = function(){}
var a="bbb"
(function(){
	alert(1);
}());

所以本人是比较推荐第1种写法,容错性比较好!

相关扩展阅读:
javascript匿名函数的写法、传参和递归:http://js8.in/2011/08/03/javascript%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0/
JavaScript中的匿名函数及函数的闭包:http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html

对于一个匿名函数,我们会更喜欢用下面的形式实现立即调用/执行效果:

(function(){
alert("立即调用的函数表达式")
}());

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

其实任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。比如:

!function(){alert('立即调用的函数表达式')}() // true
+function(){alert('立即调用的函数表达式')}() // NaN
-function(){alert('立即调用的函数表达式')}() // NaN
~function(){alert('立即调用的函数表达式')}() // -1

上述写法都是为了立即调用/执行效果,当然前提是不在乎其返回值。

对于写法实现上,可扩展阅读下面这篇文章:
function与感叹号:http://swordair.com/function-and-exclamation-mark/

另有一篇文章,算是概念的纠正吧:

自执行匿名函数和立即调用/执行的函数表达式的区别:http://www.cnblogs.com/TomXu/archive/2011/12/31/2289423.html

除此之外,匿名函数可以通过下面的方式进行传参:

(function(win, doc){
	var $ = function(id){
		return doc.getElementById(id);
	};
	win.$ = $;
})(window, document);

最后上一个立即调用/执行的函数表达式的应用实例源码,这是实现图片banner广告循环切换的最基本原型代码:

<style>
			*{margin: 0;padding: 0;}
			.banner{position: relative;}
			.banner li{color: #f00;font-weight: bold;text-align: center;width: 300px;height: 150px;line-height: 150px;position: absolute;left: 0;top: 0;}
			.banner li:nth-child(1){background-color: #63AF2E;}
			.banner li:nth-child(2){display: none;background-color:#80FFFF;}
			.banner li:nth-child(3){display: none;background-color: #780000;}
		</style>
<ul class="banner">
			<li>1</li>
			<li>2</li>
			<li>3</li>
		</ul>
<script>
		(function(){
					var i=0;
					setTimeout(function(){
						++i>=$(".banner li").length?i=0:"";
						$(".banner li").eq(i).fadeIn().siblings().fadeOut();
						setTimeout(arguments.callee,1000);
					},1000);
				}());
		</script>


上述代码,之所以用到立即调用/执行的函数表达式,主要作用是模仿块级作用域(也叫私有作用域):避免向全局作用域中添加过多的变量和函数。这样每个开发人员既可以使用自己的变量,又不必担心会影响或搞乱全局作用域。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值