Web前端|轻松理解JavaScript匿名函数、自执行函数、闭包函数、回调函数

匿名函数 没有命名的函数称之为匿名函数。

function (s){ alert(s); }

如何调用匿名函数?
1.变量接收法
这种写法其实跟具名函数已区别不大。
var show=function (s){ alert(s); } show("tang");

2.自执行函数法
(function(s){ alert(s); })("zhi");

//还可以接收返回值: var s=(function(s){ return s; })("chao"); alert(s);

自执行函数 自执行函数不是真的是自己就能发生调用,而是使用了一种特殊的调用函数的写法,这种写法将函数定义和函数调用揉和在一起,给人的感觉就好像函数自己会执行一样,所以叫自执行函数。
作用:
立即执行一个函数。
自执行函数有很多种写法:
1.两个并列的小括号
(function(s){ alert(s); })("zhi");

【Web前端|轻松理解JavaScript匿名函数、自执行函数、闭包函数、回调函数】2.两个嵌套的小括号
(function(s){ alert(s); }("zhi"));

3.匿名函数前加上操作符"+"、"-"、"~"、"!",不过这种写法不支持接收返回值
+function(s){ alert(s); }("tang"); -function(s){ alert(s); }("tang"); ~function(s){ alert(s); }("tang"); !function(s){ alert(s); }("tang");

4.全部写法:
括号型(大众写法): ( function() {}() ); ( function() {} )(); [ function() {}() ]; 保存变量型(屌丝写法): var f = function() {}(); **下面的写法都不支持返回值!** 符号型(文艺青年写法): + function() {}(); - function() {}(); ~ function() {}(); ! function() {}(); 关键字型(非主流杀马特写法): void function() {}(); new function() {}(); new function() {}; delete function() {}(); typeof function() {}(); 表达式型(非主流之王,杀马特之帝,千万别这样写,别人会打你的): //1随便换成什么都行,如""、0、0.0 1,function() {}(); 1^function() {}(); 1>function() {}(); 1&function() {}(); 1==function() {}(); 1+function() {}(); 1-function() {}(); 1*function() {}(); 1/function() {}(); 1%function() {}();

刚才已经说了,自执行函数只是使用了一种js中的特殊调用方式,所以,具名函数也是可以使用这种调用方式的:
(function temp(s){ alert(s); })("chao"); (function temp(s){ alert(s); }("zhi")); ~function temp(s){ alert(s); }("tang");

匿名函数+自执行函数 javascript中没用私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中声明了一些变量,可能会被其他人不小心用同名的变量给覆盖掉,根据javascript函数作用域链的特性,可以使用这种技术可以模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,所以( function(){…} )()内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。
JQuery使用的就是这种方法,将JQuery代码包裹在( function (window,undefined){…jquery代码…} (window)中,在全局作用域中调用JQuery代码时,可以达到保护JQuery内部变量的作用。
闭包函数 闭包就是函数的嵌套,内层的函数可以使用外层函数的所有变量,然后外层返回内层函数本身,我们称内层的函数为闭包函数。
代码解释:
function f1(){ var i=0; //f2函数访问不到i变量 return function(){//这就是内层的闭包函数 alert(i); //内层的函数可以访问i变量 } } function f2(){ var f3=f1(); //接受闭包函数 f3(); //调用闭包函数 }

为什么要用闭包?
因为JavaScript作用域的限制,外部没法访问函数的内部变量,闭包函数可以解决这一问题。
还有一个原因就是让这些变量的值始终保持在内存中也可以使用闭包。
javascript垃圾回收跟java类似,如果一个变量没有任何地方引用它,那么垃圾收集器就会回收该变量,但如果有一个闭包函数引用了该变量,那么这个变量及时在该函数运行结束,也会驻留在内存不会被回收。
回调函数 回调函数指在参数中传入的函数,主函数选择一个时机调用这个参数传来的函数。
代码解释:
function f1(callback){ var p="我是回调参数"; callback(p); } function f2(){ f1(f3); } function f3(callbackParam){ alert("我是一个回调函数:"+callbackParam); }

回调函数不一定需要在f1运行过程中执行,也可以是异步的:
function f1(callback){ var p="我是回调参数"; setTimeout(function(){ callback(p); },4000); } function f2(){ f1(f3); } function f3(callbackParam){ alert("我是一个回调函数:"+callbackParam); }

    推荐阅读