干货!干货!干货!彻底理解预编译!!!
本文会详细解释Js预编译
Javascript是解释性语言,什么是解释型语言?
答:逐行解析 逐行执行。
预编译是啥?
答:在js被解析之前,js解析引擎会把整个文件进行预处理 这个预处理的过程就被称为预编译。
预编译是啥时候发生的?
答:在函数执行的前一刻。
console.log(test); //打印什么?
var test = 100;
function test(){ //打印什么?
console.log(test); //打印什么
}
test();
自己动手去试一试吧
全局对象 (Global Obejct) 我们简称GO
浏览器环境中 js内部引擎会整个script标签中的内容 产生window对象 ,window是全局对象,是完全等于GO的,GO === window
全局变量
在script中声明的变量为全局变量,还有未经声明就直接赋值的,也是属于window对象的,而window === GO,所以也是属于GO的
var test = 100;
test1 = 100; //未经声明的变量,也属于window
console.log(window.test);
console.log(window.test1); //可以正常输出
自己动手去试一试吧
全局函数
在script中声明的函数为全局函数
function test1() {
console.log('i like fish');
}
test1()
激活对象 (Activation Obejct) 简称AO
函数调用时候产生AO 用来保存当前函数内部的执行环境
函数调用结束后销毁 如果函数重新调用 会创建一个新的AO
提示:这里略微看一下就行
局部变量
啥事局部变量?
答:在函数内部声明的变量叫做局部变量 作为AO对象的属性存在
局部函数
在函数内部声明的函数叫做局部函数 局部函数作为AO对象的方法存在
function test() {
function test1() {
console.log('i like fish')
}
test1();
}
test();
自己动手试试吧
经过我们上面知识的铺垫,我们进入正题
全局预编译
- 第一步:创建全局对象GO (window对象);
- 第二步:变量声明提前,将所有变量的声明放在最前面,赋值为undefined,存在变量名相同, 只声明一个。
- 第三步:函数声明提前,将函数声明放在最前面。函数名如果跟变量名相同,函数名会覆盖变量名 值是函数体
- 第四步:全局预编译结束,结束后代码从上到下
console.log(test); //输出 function test() {};
var test = 100;
console.log(test); //输出 100;
function test() {
console.log(111);
}
console.log(test); //输出 100;
全局预编译环节分析:
1 创建GO对象
2 变量声明提前 值为undefined
01. 找到了变量声明:var test = 100;
02. test: undefined
3 函数声明提前,同名覆盖 值为函数体
01. 找到了函数声明 function() {...}
02. test: function(){}
4 预编译结束 从上到下执行代码
题目分析:
预编译最后一个环节test = function() {...}
所以打印function(){}
代码执行到var = 100;的时候 test里面的值从function(){}
更换为100,所以第二个console.log打印的还是100 到了函数
体的时候 会略过,因为被提升了,直接输出下面的100;
自己动手试试吧。
函数预编译
- 第一步:创建AO对象
- 第二步:找出形参和变量声明,值赋予undefined
- 第三步:实参,形参值相统一
- 第四步:在函数体里面找到函数声明,值赋予函数体
function test1(a) {
console.log(b); //1 输出 function b(){}
var b = 0;
console.log(b); //2 输出 0
console.log(a); //3 输出 function a(){}
function a() {
}
function b() {
}
}
test1(1);
分析函数预编译
1 创建AO对象
2 找出形参,变量声明 值为undefined
01. 找到了形参a
a: undefined
找到了变量声明 var b = 0;
b: undefined
3 实参,形参 值统一
02. a: 1
b: undefined
4 找出函数声明 值为函数体
03. a: function a() {}
b: function b() {}
题目分析:
预编译结束之后,会从上到下执行代码 第一个打印function b(){},
没问题 当执行到var b = 0;的时候,会把b里面的函数更改为0,
下面打印0,最后输出函数a没问题,因为预编译最后环节 a里面保存
的是function a(){}
自己动手试试吧。
小提示:在预编译环节 不管你有没有if判断之类的条件语句,预编译都会给你打破,把里面的值拿出来
到这里也就和大家说再见啦,下期再见。