一. 下面代码用于理解函数的声明
和调用
。
function makeCounter() {
// 只能在makeCounter内部访问i
var i = 0;
return function () {
console.log(++i);
};
}
// 注意,counter和counter2是不同的实例,分别有自己范围内的i。
var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2
var counter2 = makeCounter();
counter2(); // logs: 1
counter2(); // logs: 2
- 首先
声明了makeCounter函数
,该函数中定义了局部变量i
,返回值是一个函数
,这里要注意的是一个函数的声明
; - 使用
表达式的方式
创建实例,将makeCounter函数的执行结果
赋给变量counter
,此时counter得到的是makeCounter的返回值
,即function () {console.log(++i);}
; - 因此,
counter()
表达式中,()
的作用就是用于执行function () {console.log(++i);}
,在控制台中打印出结果。
二. 通过上面的例子,我们有必要认识一下js表达式,用于帮我们理解了立即调用的函数表达式
- 表达式分为原始表达式和复杂表达式,上述
counter
是一个标识符
,就是属于原始表达式; - 而
function(){}
只是一个函数声明,不属于表达式,因此,在其后面加上()
,并不是立即调用函数表达式; - 尽管是命名函数也好,如
function fn(){}
,即使在后面加上()
,也无法实现立即执行效果,它同样只是一个函数声明,不属于表达式
。 - 只有把它赋给一个变量,
var counter2 = makeCounter();
在标识符counter2后面加上()
,才是对其进行调用。 - 因此,现在的方法就是
把函数声明变为表达式
,如何转换呢?
三. 书写立即调用的函数表达式的方法,见下面代码:
// 下面2个括弧()都会立即执行
(function () { /* code */ } ()); // 推荐使用这个
(function () { /* code */ })(); // 但是这个也是可以用的
- 首先,我们来理解一下
小括号()
的作用,()
除了作为分组运算符应用于数学运算外,在js中,它还有个重要的作用,就是用于区分一个代码是函数声明还是函数表达式
,见下面代码:
function func(){};//函数声明方式
(function func(){})//函数表达式方式
结合这段代码和上面的代码,我们就可以清楚的看出,()在代码中的作用,就是将函数声明转换为函数表达式
,这就解答了我们上述5中的问题。
- 我们也可以通过一个其它的例子来加深理解,这就是
eval()
方法的使用。该方法的一个常用的应用场景,就是使用eval()函数将json格式字符串转换为对象
的时候,需要多嵌套一层小括号。