一、变量的使用
(一)变量的获取规则
首先,在自己的作用域内部查找,如果有,就直接拿来使用。
如果没有,就去上一级作用域查找,如果有,就拿来使用。
如果没有,就继续去上一级作用域查找。
依次类推 如果一直到全局作用域都没有这个变量,那么就会直接报错。
var num = 100 ;
function fn() {
var num2 = 200
function fun() {
var num3 = 300;
// 自己作用域内有,拿过来用
console.log(num3)
// 自己作用域内没有,就去上一级作用域里面找,发现有,拿过来用
console.log(num2)
// 自己这没有,上一级里也没有,再上一级到全局作用域,有, 直接用
console.log(num)
// 自己没有,一级一级找上去到全局都没有,就会报错
console.log(a)
}
fun()
}fn()
(二)变量赋值规则
先在自己作用域内部查找,有就直接赋值。
没有就去上一级作用域内部查找,有就直接赋值。
再没有再去上一级作用域查找,有就直接赋值。
如果一直找到全局作用域都没有,那么就把这个变量定义为全局变量,再给他赋值。
function fn() {
num = 100
}
fn()
// fn 调用以后,要给 num 赋值
// 查看自己的作用域内部没有 num 变量
// 就会向上一级查找
// 上一级就是全局作用域,发现依旧没有
// 那么就会把 num 定义为全局的变量,并为其赋值
// 所以 fn() 以后,全局就有了一个变量叫做 num 并且值是 100
console.log(num) // 100
二、函数提升
在js中有时变量的使用在声明之前,如下代码可以正常运行
<script>
fun();
function fun(){
alert("我在后面");
}
</script>
哦,懂了,这是js把函数声明提到前面了,
但我又发现下面的代码却不能正常执行,并报如下错误
<script>
fun();
var fun = function(){
alert("我在后面");
}
</script>
Uncaught TypeError: fun is not a function
这个错误的意思是类型错误,说明fun不是一个函数。为什么说fun不是一个函数呢?我明明定义的是函数啊。再想一想,显而易见的是第一种我们是用了声明式,第二种使用的是赋值式,难道只有声明提前而赋值不会提前吗?那我们来做个小实验。
console.log(sum);
var sum = 5;
如上代码,
如果只有声明提升,那么控制台应该显示undefined
如果声明与赋值都提升的话,那么控制台显示的应该是sum的值:5
从结果来看,我们能得出此时只有变量声明提升了,而后面赋值语句并没有提升所以打印的时候,sum未赋值,打印结果为undefined。
通过这个小例子大家应该明白为什么第一个函数可以正常运行但是第二个不可以运行了吧。简单的来说就是:函数提升只会提升函数声明,而不会提升函数表达式。
总结:函数提升和我们的预解析有着很大的关系,只要能明白预解析的机制就很容易理解函数提升。
变量声明分成两个部分 :
1. 变量声明; 只有这个部分发生了提升;
2. 变量赋值;