在ES5中,js的作用域不同于别的语言,{}不构成块级作用域,作用域是靠函数形成的。也就是说只有全局作用域和函数作用域,并没有块作用域。
例如:
for(var i = 0; i < 3; i++){
var j = 4
}
console.log(i) //3
console.log(j) //4
再来看作用域链,我的理解,怎么找一个变量是在哪里声明的就是靠的作用域链原理。
记住以下三点基本就可以搞定啦。
- 函数在执行的过程中,先从自己内部找变量
- 如果找不到,再从创建当前函数所在的作用域去找, 以此往上
- 注意找的是变量的当前的状态
举个例子:
var a = 1
var b = 2
function sum(a) {
var b = 3
console.log(a + b)
}
sum(2) //5
上面的例子显而易见,那如果函数里面找不到变量呢?那么它会在当前函数的词法作用域中去找,及函数声明的作用域中。
// sum函数中没有变量b的声明,所以取全局的
var a = 1
var b = 2
function sum(a) {
console.log(a + b)
}
sum(2) //4
再来看看下面这个例子
var a = 1
function fn1(){
function fn2(){
console.log(a)
}
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
var fn = fn1()
fn()
最后会输出console.log(a),那么a取值会是fn3中调用fn2的地方找吗,还是fn2声明的作用域中找呢。上文已经有解释,那么结果就是2。