首先先下个结论,javascript代码在执行时表面并不是由上到下一行一行执行的。
什么是声明的提升?
1.众所周知var a;如果a不赋值的话,a的值为undefined。
var a;
console.log(a); // undefined
- 未声明直接赋值的变量
a = 1;
console.log(a); // 1
上面的代码块为什么打印的是1,而不是undefined呢?很明显a是声明了的,但是a声明在全局作用域了还是局部作用域了呢?
- 在局部作用域给未声明的变量赋值
(function() {
a = 1;
})()
console,log(a); // 1
这时可以得到结论:变量a被声明为了全局变量
下面回到正题:
a = 1;
var a;
console.log(a); // 1
这时候a的值为1,是为什么呢?还是因为a被声明为全局变量了么?先来看下一个例子:
(function() {
a = 1;
var a;
console.log(a); // 1
})();
console.log(a); // ReferenceError
很奇怪,第二个console的结果a是未被定义的。现在回想或者到文章开头看看一开始的结论,是不是明白了点什么。那代码执行真正的顺序是什么样的呢?往下看
console.log(a); // undefined
var a = 1;
a的值是undefined,说明a在console之前就已经声明了,但是并没有赋值。上面代码块可以理解为一下代码:
var a;
console.log(a);
a = 1;
现在可以有第二个结论了:
引擎会在解释 JavaScript 代码之前首先对其进行编译。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。所以正确的思路应该是: 所有变量的声明都会在任何代码被执行前首先被处理(函数也一样)。
当我们看到var a = 1;时,javascript其实是将它看成两个语句:var a; 和 a = 1; 声明是在编译阶段进行的,而赋值操作等待在原地等待被执行。这就叫提升。
注意:提升只会提升到当前作用域!
网友评论