变量提升
这里只是用伪代码的形式来说明,实际上变量声明只是执行上下文有关,推荐阅读 JavaScript深入之变量对象
太长不看篇
函数参数 > 函数声明 > 变量声明
变量声明
首先想用一个伪生命周期来说这个事情,假设这段代码分为两个阶段,初始化阶段和赋值阶段; 看下面一段代码,用伪系统的话来阐述
console.log(a);
var a = 10;
如果按照上面的声明周期来说,首先变量 a 会在作用域注册一个变量(如果没有)默认赋值为 undefined
初始化完成后,开始执行代码,第一行语句的时候因为变量 a 未经过赋值阶段,这一阶段的值是 ndefined
,所以打印的结果自然也就是 undefined
;
在第二行的时候变量 a 会经过赋值阶段,这时变量 a 的值就是 10 了。
函数声明
函数声明与变量声明规则基本一致,优先级比变量声明要高
是不是只说这一句话大家有些失望,如果只是单独来说函数声明未免太没意思,下面就结合变量声明来说说函数声明,毕竟代码只有变量声明就做不到有趣了。
a();
var a = 10;
function a() {
console.log(5);
}
上面的执行结果是打印数字 5,为什么会出现这种情况呢?上面我们已经说了函数声明优先于变量声明,那么上面代码实际可以拆封成下面形式
function a() {
// ...
}
a();
a = 10;
你可能还有疑惑,事实上如果变量提升的时候发现已经存在变量就会默默忽略掉,比如上面的代码变量 a 已经是一个函数了,那么变量声明的 a 会被忽略。
最后说下函数参数,参数也是变量的一种形式,它的优先级最高,但是同样会受到函数声明的影响
function a(x) {
console.log(x);
function x() {}
}
a(5);
这里输出结果是函数 x,原因是函数声明提升的时候会执行一个覆盖操作,就像我们写代码x = 5
这样
最后
这里说的有很多地方不足,只是自己的见解,更推荐一篇文章10 分钟理解执行上下文
最后根据上面的内容讲解一下他布置的一到题目
console.log(x);
var x = 10;
console.log(x);
x = 20;
function x() {}
console.log(x);
if (true) {
var a = 1;
} else {
var b = true;
}
console.log(a);
console.log(b);
首先初始化阶段,function x
最先被提升,后面的变量提升因为已经存在函数 x 的原因会被忽略 第一个 console 输出的是函数 x
,
之后执行到第二行代码的时候 x
被改变变成 10
,第二个 console
输出为 10
,之后继续被赋值为 20
,第三个 console
输出为 20
,
第四个和第五个 console
的输出分别为 1
和 undefined
,这是因为 es5 的环境下并不存在块级作用域,变量 a
和 b
会执行变量提升这一步骤,
不同的是 a
被赋值为了 1
,而 b
因为没有执行到 var b = true
所以值还是 undefined
。