1 JS引擎运行 js
我们JS引擎运行js分为两步:预解析 、代码执行。
1.1 预解析
预解析JS引擎会把js里面所有的var还有function提升到当前作用于的最前面。
- 变量提升:就是把所有的变量声明提升到当前作用域的最前面,不提升赋值操作。
- 函数提升:就是把所有的函数声明提升到当前作用域的最前面,不调用函数。
1.2 代码执行
按照代码书写的顺序从上往下执行。
2 代码案例
2.1 第一个案例
var num=10;
fun();
function fun() {
console.log(num);
var num=20;
}
// 输出为 undefined
// 相当于以下代码
var num;
function fun() {
var num;
console.log(num);
num=20;
}
num=10;
fun();
2.2 第二个案例
var num;
function fun() {
console.log(num);
var num=20;
console.log(num);
}
fun();
// 输出为 undefined 20
2.3 第三个案例(重点)
面试题 重点
在函数内部,没有声明直接赋值的变量也属于全局变量。
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a=b=c=9;
// 相当于var a=9; b=9 ,c=9;
console.log(a);
console.log(b);
console.log(c);
}
// 输出为 9 9 9 9 9 undefined
// 相当于以下代码
function f1() {
var a=9;
b=9; c=9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
// 输出为 9 9 9 9 9 undefined
2.4 第四个案例
在立即执行函数中,var a = 20; 语句定义了一个局部变量 a,由于js的变量声明提升机制,局部变量a的声明会被提升至立即执行函数的函数体最上方,且由于这样的提升并不包括赋值,因此第一条打印语句会打印undefined,最后一条语句会打印20。
由于变量声明提升,a = 5; 这条语句执行时,局部的变量a已经声明,因此它产生的效果是对局部的变量a赋值,此时window.a 依旧是最开始赋值的10,
var a = 10;
(function () {
console.log(a) // undefined
a = 5
console.log(window.a) // 10
var a = 20;
console.log(a) // 20
})()
删除 var a = 20;后,第一次输出发现a=10 是全局变量,修改a的值为5后输出为5
var a = 10;
(function () {
console.log(a) // 10
a = 5
console.log(window.a) // 5
console.log(a) // 5
})()