什么是匿名函数?
在前端面试中面试官基本都会问到什么是匿名函数、什么是闭包函数。
本文就先来说一下什么是匿名函数。
匿名函数顾名思义就是没有名字的函数,通常我们所写的函数都是这样的:
1 function do(){ 2 // 执行代码 3 }; 4 5 // 调用 6 do();
这种写法是定义了一个名为do的函数,并通过函数名称进行调用。
那如果没有名字是什么样子的啊?
1 function () { 2 // 执行代码 3 };
这种写法在编译的时候会报错:
Uncaught SyntaxError: Unexpected token (
这是为什么呢?原来时因为浏览器在进行语法分析的时候发现这个函数根本没法执行。
那要为什么还要匿名函数呢?在编程语言中如果又个编码方式那这种编码方式肯定是能正常运行的,那该如何让匿名函数跑起来呢?再看下面的例子:
var do = function () { // 执行代码 } do();
这种函数大家肯定都知道,其实这种写法就是将匿名函数复制为变量do,再通过变量名执行函数。
(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;
总结:自执行函数的优点是为了保证自执行函数中的变量不会受到其他环境的污染。