JS中作用域与变量提升.md

ES5中for循环定义的全局变量

下面表达式输出的结果为:

1
2
3
4
5
6
7
8
9
10
11
12
for(var i=1;i<4;i++){
setTimeout(function () {
console.log(i)
},0)
}
console.log(i)

//4 这是for循环执行完成之后,i++此时的i已经变成4,所以for循环之后的所有关于i的值都是4

//4
//4
//4

因为在表达式中定义的var i是全局作用域变量,任何一个地方都可以访问到,并且一定注意,在for循环内,如果都是同步执行的话,则i的值为3,但是如果是类似异步的,for执行完毕之后为i为4,所以所有i的值都为4.

立即执行函数

先看一段代码:

1
2
3
4
5
function (){ ... }();

//或者

function fName(){ ... }();

执行结果为: SyntaxError: Unexpected token (,为什么会有这个错误呢?

要理解两个概念

函数声明

1
2
3
function name([param[, param[, ... param]]]) {
statements
}

函数表达式

1
//一个匿名函数的函数表达式,被赋值给变量f2:
1
2
3
4
5
6
7
var f2 = function() {
console.log("f2");
}

//通过()来调用此函数

f2();

所以我们来看之前报错的原因,这是一个函数声明,后面再接一个() ,js引擎看到function关键字之后,认为后面跟的是函数定义语句,不应该以圆括号结尾,解决这个问题就是让引擎知道,圆括号前面的部分不是函数定义语句,而是一个表达式,可以对此进行运算。改写成这样。

1
2
3
4
5
(function(){ /* code */ }()); 

// 或者

(function(){ /* code */ })();
带参数(parameter)

有时候看到这样的一种形式,括号中传递一个参数。

1
(function (p) { return p})(parameter);

立即 执行的括号中传入了一个参数,执行的过程中此参数就是函数传入的参数。