说变量声明提升之前,先抛出一个疑问:JavaScript是解释型语言,还是编译型语言?
对于这个问题,几乎所有初学者都坚定不移的给了我答案:“JavaScript是解释型语言”,但是随着你对JavaScript的了解,会产生疑问,解释性语言怎么还会有变量提升。因此,说JavaScript是一个解释性语言其实并不准确,因为JavaScript代码刚好在执行前一瞬间,会被编译(具体解释需要很长篇幅,下次再说)
由于误以为JavaScript是纯粹的解释型语言,会对下面这段代码产生误解
a = 1;
var a;
console.log(a);
按照我们正常的思路,会想var a
时候我们将a
这个变量重新定义了,因此,最后打印的a
会是undefined
,然而事实上真正的结果是1
。
对于语句 var a = 1 ,其实应该被分成两个部分
- var a 声明变量:在编译阶段被处理的事情
- a = 1 变量赋值:在执行阶段发生的事情
所以,就在执行的前一瞬间,刚好发生了变量声明提升,因此刚刚那段代码变成了这个样子
var a;
a = 1;
console.log(a); // 毫无疑问,a = 1
似乎弄懂了变量声明提升?那就看一下这个问题
console.log(a);
var a = 1;
结果是undefined
,但一定有人坚定的认为结果应该是1
,还有人认为会报错,认为报错的同学,回去上一条看看变量声明提升,认为结果是1
的同学,我再多解释一下 我一直在说的,是变量声明提升,并没有说赋值会提升,因此这个代码在执行前的一瞬间是这样子的
var a;
console.log(a);
a = 1;
JavaScript里对于定义但没有赋值的变量,毫无疑问,就是undefined
。
变量声明提升,是不能突破作用域的,我们还是来看一个例子
console.log(a);
function test () {
console.log(a);
var a = 1;
}
test();
!!!!!!!!!!!!报错了
很显然,函数test
形成了一个函数作用域,函数内部声明变量a
会提升到函数test
作用域的最前面,但不会突破函数作用域,跑到全局作用域里面取去。
删掉全局作用域被错误使用的 a
function test () {
console.log(a);
var a = 1;
}
test(); // 如我们所料,结果是undefined