1.js引擎运行js分为两步:预解析和代码执行
(1)预解析js引擎会把js里面所有的 var 和 function 提升到当前作用域的最前面;
(2)代码执行 按照代码书写的顺序从上往下执行。
2. 预解析分为 变量预解析(变量提升)和函数预解析(函数提升)
(1)变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作;
(2)函数提升:就是把所有的函数声明提升到当前作用域的最前面 ,不调用函数。
案例一
<script>
var num = 10;
fun();
function fun() {
console.log(num); //underfine
var num = 20;
}
// 相当于执行以下代码
var num;
function fun() {
var num;
console.log(num);
num = 20
}
num = 10;
fun();
</script>
案例二
<script>
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a); //underfine
console.log(b); //9
var a = '123';
}
// 相当于执行以下代码
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
</script>
案例三
<script>
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
// 相当于执行以下代码
function f1() {
var a = b = c = 9;
// 相当于 var a=9; b=9; c=9; b 和 c 直接赋值 没有var声明 当 全局变量
// 集体声明 var a=9, b=9, c=9
console.log(a); //9
console.log(b); //9
console.log(c); //9
}
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //报错
</script>
案例四
<script>
function b() {
a = 10;
return;
}
var a = 1;
b();
console.log(a); //10
// 相当于执行
function b(){
a=10; //全局变量
return;
}
var a;
a=1;
b();
console.log(a); //10
//因为先执行a=1,后面再执行函数,由于函数里面的a是全局变量,函数里面没有a的地址,就会
//往外面找,结果找到了a的地址,然后再把a=10 赋值给a
</script>
案例五
<script>
var a = 1;
function b() {
a = 10;
return;
//a函数声明,提前变量a,将a认为是函数b作用域的变量,具有局部效果
function a() { }
}
b();
console.log(a);
// 相当于执行 function b()相等于var b=function()
var a;
var b;
b = function () {
var a;
a = 10;
return;
a = function () { }
}
</script>