- 函数声明
function funcName(){
};
console.log(funcName); // 打印结果是funcName这个函数体。
声明一个函数funcName,funcName就是函数名,函数名是函数声明的必要组成部分,函数其实就是另一个类型的变量,函数名称相当于变量名,新声明的函数体会赋值给这个变量名,之后调用该函数的时候都需要通过该变量名进行调用。
- 函数表达式
// 命名函数表达式
var funcName = function abc() {};
console.log(funcName); // 打印函数体function abc(){}
console.log(abc); // 报错(abc is not defined)
在这个函数表达式中,函数名称为abc,其实上,这个名称abc变成了函数内部的一个局部变量,并且指代函数对象本身,在abc函数内部打印abc的打印结果是abc函数体本身。
var funcName = function abc() {
console.log(abc); // 打印结果是function abc() {console.log(abc)}
};
所以,在全局console.log(abc);肯定会报错,因为abc是局部变量,全局是拿不到的,这个函数表达式会忽略函数的名称,调用的时候要通过变量名进行调用——funcName();
// 匿名函数表达式
var funcName = function () {};
匿名函数表达式顾名思义就是没有名字的函数表达式,一般情况下,我们所说函数表达式就指匿名函数表达式,因为函数表达式会忽略函数的名称,会变成匿名函数表达式,不如直接写成匿名函数表达式。
函数表达式与函数声明不同的是,函数声明只是声明了一个函数,在预编译的时候,函数声明的声明提升函数体也提升,所以不管你是在函数声明之前调用还是在之后调用,都能正常执行。
demo(); // 结果是'a'
function demo(){
console.log('a');
};
demo(); // 结果是'a'
而函数表达式在预编译时,是变量名提升,只有当执行到函数表达式所在行的代码时,才将函数体赋值给该变量,所以在函数表达式之前调用该函数会报错,只能在之后调用。
demo(); // 报错
var demo = function (){
console.log('a')
};
demo(); // 结果是'a'
- 匿名函数
匿名函数顾名思义就是没有名字的函数。(匿名函数有多种用途,写在文末)
function () {};
既然是没有名字的函数,那我们要怎样找到它调用它呢?这里要提到两种方法。
第一种方法是上面已经说到的匿名函数表达式,即将匿名函数赋值给一个变量,然后通过变量名去调用。
var abc = function (){};
abc();
第二种方法就是接下来要说的立即执行函数。
- 立即执行函数
立即执行函数有两种写法:
// 第一种 w3c标准建议使用这一种
(function (){})();
// 第二种
(function(){}());
这里有两个括号有点疑问,在解释两个括号的作用前,我们先明确几点:
1.只有表达式才能被执行符号执行,函数声明是不能被执行符号执行的。
2.能被执行符号执行的表达式,这个函数的名字就会被自动忽略(放弃名字)。
3.能被执行符号执行的表达式基本上就是立即执行函数。
因为函数声明是不能被执行符号执行的,除非通过函数名调用,只有表达式才能被执行符号执行(匿名函数又没有函数名,另外的办法就是把它变成表达式)。
function (){
console.log('a'); // 报语法错误,因为只有表达式才能被执行符号()执行
}();
(function (){})()
所以此处匿名函数两边的括号运算符,作用是把函数转换为表达式(至于怎样转换的,更深层的原理有兴趣的童鞋可以研究研究,后续我会进行补充的),后面的括号为执行符号,(function (){})()就相当于匿名函数表达式的执行。
(function (){})()和(function(){}())写法其实没多大区别,(function(){}())也是一直等价的表达式,但是w3c标准建议使用第一种。
将函数声明转化成表达式的方式有很多,例如把它赋值给一个变量,再例如在函数声明前放上+运算符,-运算符,!运算符等。
// 把它赋值给一个变量
var demo = function(a){
console.log(a); // 结果为1
}(1)
// 使用+运算符
+function(a){
console.log(a); // 结果为1
}(1);
// 使用-运算符
-function(a){
console.log(a); // 结果为1
}(1);
// 使用!运算符
!function(a){
console.log(a); // 结果为1
}(1);
当表达式被执行,函数的名字就会被放弃,举两个栗子:
var demo = function(){}();
console.log(demo); // 结果会报错,因为函数名被放弃了。
+function demo(){}();
console.log(demo); // 结果会报错,因为函数名被放弃了。
匿名函数有很多作用,例如将匿名函数赋予一个变量来创建一个函数,例如赋予一个事件则成为事件处理程序,再例如用立即执行函数创建闭包防止污染全局变量等等
// 将匿名函数赋予一个变量来创建一个函数
var demo = function(){};
// 赋予一个事件则成为事件处理程序
$(selector).on('click',function(){});
// 用立即执行函数创建闭包
(function(window, undefined))(window);
本文只是简单分析以助自己理清思路,有错误之处请不吝赐教。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。