前言
本节内容将针对面试常考的预解析进行讲解。在了解预解析之前,希望大家能了解一下作用域的相关知识。
一,预解析
1.1 引子
引子1:
console.log(num);
var num = 10;
最后运行结果是什么样的?
没有报错,输出的是undefined:
引子二:
fn()
function fn () {
console.log(11)
}
同样可以正常运行:
引子三:
fun()
var fun = function() {
console.log(22)
}
结果是报错:
这些都是为什么呢?想要知道这个结果,我们就必须了解js的运行机制——预解析。
1.2 预解析
javascript解析器在运行javascript代码时分为两步:预解析和代码执行。
预解析:js引擎会把js里面的所有var还有function提升到当前作用域的最前面;
代码执行:按照代码书写的顺序从上往下执行。
预解析分为变量预解析(变量提升)与函数预解析(函数提升)
1.3 变量提升
变量提升是指把所有的变量声明提升到==当前作用域的最前面,不提升赋值操作,这就是为什么在第一个引子中,没有报错,输出undefined。
这段代码:
console.log(num)
var num = 10;
相当于执行了以下代码:
var num;
console.log(num);
num = 10;
也能解释为什么第三个引子中会报错了:
这段代码:
fun()
var fun = function() {
console.log(22)
}
相当于如下代码:
var fun;
fun()
fun = function() {
console.log(22)
}
这就是为什么会报错的原因。
1.4 函数提升
函数提升就是把所有的函数声明提升到作用域的最前面,但是不调用函数。这就可以解释第二个引子:
fn()
function fn () {
console.log(11)
}
就相当于这段代码:
function fn() {
console.log(11);
}
fn()
二,预解析案例
2.1 案例一
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
相当于:
var num;
num = 10;
function fun() {
var num;
console.log(num);
num = 20;
}
fun();
结合作用域可知,最后结果为undefined。
2.2 案例二
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
相当于:
var num;
function() {
var num;
console.log(num);
num = 20;
console.log(num);
}
num = 10;
fn();
可知最后结果是undefined和20。
2.3 案例三
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
相当于:
var a;
function() f1 {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
最后的结果是undefined和9。
2.4 案例四
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(c);
console.log(b);
console.log(a);
}
相当于:
var a = 9;
b = 9;
c = 9;
相当于:
function f1() {
var a;
b = 9;//全局变量
c = 9;//全局变量
a = 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
总结
预解析是一个很重要的版块,期望大家结合作用域一起理解。如果需要更多面试题可以参考更多面试题。
希望能对你有帮助!