在前端面试中面试官基本都会问到什么是匿名函数、什么是闭包函数。前端
本文就先来讲一下什么是匿名函数。面试
匿名函数顾名思义就是没有名字的函数,一般咱们所写的函数都是这样的:编程
1 function do(){ 2 // 执行代码 3 }; 4 5 // 调用 6 do();
这种写法是定义了一个名为do的函数,并经过函数名称进行调用。浏览器
那若是没有名字是什么样子的啊?闭包
1 function () { 2 // 执行代码 3 };
这种写法在编译的时候会报错:编程语言
Uncaught SyntaxError: Unexpected token (函数
这是为何呢?原来时由于浏览器在进行语法分析的时候发现这个函数根本无法执行。工具
那要为何还要匿名函数呢?在编程语言中若是又个编码方式那这种编码方式确定是能正常运行的,那该如何让匿名函数跑起来呢?再看下面的例子:编码
var do = function () { // 执行代码 } do();
这种函数你们确定都知道,其实这种写法就是将匿名函数复制为变量do,再经过变量名执行函数。spa
(function(){ // 执行代码
console.log("打印成功"); })();
上面代码是什么意思呢?
能够先把上面的代码分几个部分:
第一部分是括号里面的匿名函数,第二部分是加上括号的匿名函数,第三部分带上最后面执行用的括号。
匿名函数在括号内部能够当作是将匿名函数当成是一个变量,再经过括号进行执行。
(function () { // 执行代码 })(); // 至关于 var do = function() { // 执行代码 }; do();
其实向上面这种匿名函数的写法在不少地方都有用到,这种又叫自执行函数,像JQuery 等一些工具包都会用这种写法,自执行函数有哪些优势呢?
1 // 定义一个全局变量a 2 var a = 1; 3 4 (function() { 5 // 在自执行函数中也建立一个变量a 6 var a = 2; 7 console.log(a); // 2 8 })(); 9 10 console.log(a); // 1
能够看到在自执行函数中打印出来的是2,而在自执行函数中打印出来的是1;
这是为何?
由于在程序中有个名称叫作做用域,全局环境的做用域叫作全局做用域,函数中的做用域叫作函数做用域,而做用域是分层的,内部做用域中能够访问外部做用域中的变量,而外部做用域中却不能够访问内部做用域中的变量。
在内部做用域中访问变量会先在本身所在做用域中查找,若是找不到再在上一层做用域中进行查找,再找不到还会再往上查找,一直到找到全局做用域。这种一层一层的关系像链条同样因此被叫作做用域链。
再看上面代码:在自执行函数中console.log 函数访问了a变量,首先在本身所在的做用域中查找,找到了a变量,故输出了a的值2;全局环境中的console.log 函数也访问了a变量,因为外部做用域不能访问内部做用域,因此全局环境中访问的a变量只能在全局函环境中进行查找,因此输出了a的值1;
总结:自执行函数的优势是为了保证自执行函数中的变量不会受到其余环境的污染。