声明提前
要明确var a = 1;
这是一个变量的声明+赋值的过程。
声明提前就是说会把变量以及函数的声明提到代码的顶部。也就是说对于变量,只会提前var a;
的声明部分。
作用域链
js中没有块级作用域,但有函数作用域
- 函数在执行的过程中,先从自己内部找变量
- 如果找不到,再从创建当前函数所在的作用域去找, 以此往上
- 注意找的是变量的当前的状态(尤其是变量被多次赋值的时候要注意)
实例
var x = 10;
bar()
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
输出30,函数内部没有,故去函数声明所在的作用域找
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()
输出2,声明fn2()的作用域中a为2
var a = 1
function fn1(){
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
function fn2(){
console.log(a)
}
var fn = fn1()
fn()
输出1,声明fn2()的作用域中a为1
var a = 1
function fn1(){
function fn3(){
function fn2(){
console.log(a)
}
fn2()
var a = 4
}
var a = 2
return fn3
}
var fn = fn1()
fn()
输出 undefined。因为在执行fn2()的时候,a还没有被赋值,声明可以提前,而赋值不可以。