精通预编译(预解析),含经典面试题

JavaScript的执行步骤

  1. 预解析阶段,在这个阶段会检查js的语法错误,然后进行变量的提升和函数的声明
  2. 执行阶段,按照代码书写的顺序从上往下执行

这里我们主要探讨的是第一个阶段,jsv8引擎在执行js代码的时候发生了什么

预解析

  • 变量提升,就是把所有的变量提升到当前作用域最前面,不提升赋值操作
  • 函数提升,就是把所有的函数声明提升到当前作用域的最前面,不调用函数

我们来看具体的实例

console.log(num); //10
var num = 10;

这里输出10,是因为预解析,变量提升

//使用函数关键字定义函数
fn();
function fn(){
	console.log(10);//10
}

我们在函数声明前也可以调用,因为预解析,函数提升

当然了如果是函数表达式,就不能提前调用了,如

fun();
var fun = function(){
	console.log(10);
}

运行这段代码只会报错
注意一点,匿名函数不参与预编译

接下来我们来看看js引擎具体干了什么事?

首先我们了解两个词
全部对象 GO(global object)
活动对象 AO(active object)

函数体内,预编译会提前把里面的变量声明和函数声明依据规则存放在AO对象内

AO规则

  1. 在函数执行前的一瞬间,生成一个AO对象
  2. 分析参数,以形参作为该对象的属性名,实参作为属性值
  3. 分析变量声明(var 变量声明),变量名作为AO对象属性名,值为undefined,如果变量名和形参重名,则不做改变
  4. 分析函数声明(function),函数名作为AO对象属性名,函数整体作为属性值,如果遇到同名(变量或者形参名),直接覆盖(函数体覆盖属性值)

GO规则

  1. 进入script标签,需要执行代码的前一瞬间
  2. 分析变量声明(var 变量声明),变量名作为GO对象的属性名,值为undefined
  3. 分析函数声明(function),函数名作为GO对象的属性名,函数整体作为属性值,如果遇到同名(变量名),直接覆盖(函数体覆盖属性值)

经典面试题

题1

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);
}

最后输出是 9 9 9 9 9 报错

第一步预解析

  1. 生成一个GO对象 GO:{}
  2. GO:{
    f1:function(){}
    }
  3. 执行代码 f1();
  4. 因为执行了函数,所以生成了一个AO对象 f1:AO:{}
  5. f1:AO:{
    a :undefined;
    }
  6. 再来执行函数体内的代码 输出 a = 9 b = 9 c = 9
  7. 再来指向函数体外的代码 输出 c = 9 b = 9 报错 因为a是函数体内的变量,不具备全局作用域

题2

function fun(a){
	console.log(a);
	var a = 5;
	console.log(a);
}
fun(99)
  1. 执行函数的前一瞬间,生成一个AO对象
    AO:{}

  2. 分析参数,以形参作为该对象的属性名,实参作为该对象的属性值
    AO:{
    a:99
    }

  3. 分析变量声明,变量名作为AO对象的属性名,值为undefined,如果变量名和形参名相同,则不做改变,这里不做改变

  4. 分析函数声明,这里不考虑,因为里面没有函数

  5. 执行代码,一步一步开始执行
    所以第一次输出a为99
    后来a又做了一次赋值操作,所以第二次输出a为5

题3

function fun(){
	return foo;
	foo = 10;
	function foo(){
	};
	var foo = 11;
}
console.log(fun()); //f f00(){}

题4

console.log(fun()); //11
function fun(){
	foo = 10;
	function foo(){
	};
	var foo = 11;
	return foo;
}

题5

function fun(){
	console.log(a);
	if(true){
		function a(){}
	}
	console.log(a)
}
fun()

这题涉及兼容性问题,在低版本的浏览器上的运行结果不一致

猜你喜欢

转载自blog.csdn.net/weixin_42208160/article/details/107162832