文章为学习之后的笔记,如有不正确的地方,欢迎大家指正,以作修改
JS执行顺序
- 因为JS是单线程,所有代码都是从上往下执行,但是在代码执行之前,JS会将整个代码粗略的扫描一遍,低级的语法错误会报错
- JS代码中所有通过 var 关键字声明的变量都会被提前拿出来进行定义,但是不赋值
- 所有的字面量函数整体都会被提前声明
fun();
function fun(){
console.log(a);//undefined
}
var a = 10;
在以上的代码中,首先 fun() 的调用写在函数声明之前,却可以调用,也就说明了函数声明确实是被提前了,打印出的 a 是 undefined ,因为 var 关键字也会声明提前,但是只定义,不赋值,相当于以下代码 ↓
function fun(){//声明提前
console.log(a);
}
var a;//只有定义声明提前,未赋值就是 undefined
fun();
a = 10;
函数表达式的提升
fun();
var fun = function (){
console.log(a);
}
var a = 10;
有没有很意外?结果不是 undefined ,而是报错。
上面讲到函数会声明提升,但是为什么这里调用函数会报错?因为这里用的不是字面量声明,而是表达式声明,除了函数提升,上面还讲了一个通过 var 关键字的声明提升,这里就属于 var 关键字的声明提升,只是提升变量定义,并没有赋值,所以 fun 还不是一个函数。
嵌套函数中的声明提升
函数嵌套会不会影响声明提升?代码测试: ↓
var a = 10;
function fun1(){
fun2();
function fun2(){
console.log(a);
var a = 20;
}
}
fun1();
打印的结果:undefined
- a 能被打印,说明声明提升除了在全局作用域中生效,在函数作用域中同样生效。
- 作用域链是从自身向外一层一层的找,所以在打印 a 的时候,fun2 先在自身找 a ,因为声明提升,a 是已经被定义了,只是未赋值,所以结果未 undefined
变量和函数同名时声明提升
这句话的意思是,有一个变量是 a ,有一个函数是 a ,那么打印 a 输出什么结果?
function a(){
}
var a;
console.log(a);//a(){};
大家肯定认为是打印函数,正好印证了上面说的函数的提升优先级大于变量,这里确实打印出了函数,那如果我将代码再修改一下。
function a(){
}
var a = 10;//**注意,这里修改了**
console.log(a);//10
打印的结果变成了 10 ,上下的代码区别很明显,上面个代码的 a 并没有赋值,所以打印的是函数,下面个赋值了,所以打印的是 10
- 在JS代码中,如果函数变量同名,变量赋值了就优先提升变量
- 如果变量未赋值,就优先提升函数
- 注意:这里的结果不会受到变量与函数位置的影响,就算变量声明在函数的上面,只要赋值了就会得到变量的值,哪怕赋值为 undefined