JS变量提升

在JavaScript中,当变量被声明时,声明会被提升到它所在函数的顶部,并被赋予undefined值。这就使得在函数的任意位置声明的变量存在于整个函数中,尽管在赋值之前,它的值一直为undefined。
像这样:

1
2
3
4
5
function(){                             function(){
console.log(v); ------------> var v;
var v = 1; ______________/ console.log(v);
\------------> v = 1;
} }

左边和右边的函数是等价的。JavaScript的变量声明会被提升到它们所在函数的顶部,而初始化仍旧在原来的地方。

JavaScript引擎并没有重写代码:每次调用函数时,声明都会重新提升。

1
2
3
4
5
6
7
8
function prison(){
//logs 'undefined'
console.log(prisoner);
var prisoner = 'Now I am defined';

//logs 'Now I am define'
console.log(prisoner);
}

接下来作用域和变量提升在一起后出现比较神奇的现象。比如这样的代码我们很容易知道是输出’Regular Joe’

1
2
3
4
5
6
var regular_joe = 'Regular Joe'; //regular_joe在全局作用域中定义
function prison(){
//logs 'Regular Joe'
console.log(regular_joe);
}
prison();

但是接下来这个呢?我们会惊奇地发现输出的是undefined!

1
2
3
4
5
6
7
8
var regular_joe = 'Regular Joe'; //regular_joe在全局作用域中定义
function prison(){
//logs 'undefined'
console.log(regular_joe);
var regular_joe;

}
prison();

原因就是在prison局部函数中声明了regular_joe了,然后这个声明提升到prison函数的顶部,而按照JS的作用域链,JavaScript引擎发现已经在局部函数里面找到regular_joe了,就使用了它的值:undefined,而不会再向上找。
——关于作用域链具体可参见 [ JS作用域链 ]