介绍
预编译又称为预处理,是做些代码文本的替换工作。是整个编译过程的最先做的工作。
- 处理以# 开头的指令 , 比如拷贝 #include 包含的文件代码,#define 宏定义的替换 , 条件编译等,就是为编译做的预备工作的阶段。
主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。
C 编译系统在对程序进行通常的编译之前,首先进行预处理
预处理功能
c 提供的预处理功能主要有以下三种:
- 宏定义。
- 文件包含。
- 条件编译。
预编译(函数执行前)
- 创建AO对象(Active Object)
- 查找函数形参及函数内变量声明,形参名及变量名作为AO对象的属性,值为undefined
- 实参形参相统一,实参值赋给形参
- 查找函数声明,函数名作为AO对象的属性,值为函数引用
预编译(脚本代码块script执行前)
- 查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined
- 查找函数声明,函数名作为全局对象的属性,值为函数引用
我先给大家举几个预编译的小例子:
var a = 123;
console.log(a);
此时他返回的值会是123;
但如果我们调换位置:
console.log(a);
var a = 123;
我们得到的结果便会是undefined。
列如
a=10;
---->window.a=10;
一切声明的全局变量,全是window的属性
那么window是干什么的?
window就是全局的域
var a=123;
全局变量首次放到电脑磁盘里面就是window
如果你要访问之前定义的a的时候他会先去window里面找a
其实就是
var a=123;
console.log(a)—>window.a其实就是访问的window.a
window里面是全局变量没有局部变量!
预 编 译 发 生 在 函 数 执 行 的 前 一 刻
function fn(a){
console.log(a);
var a = 123;
console.log(a);
function a(){}
console.log(a);
var b = function () {};
console.log(b);
}
fn(1)
- .创建AO对象,Activation Object (执行期上下文)
AO{ }
- 找形参和变量的声明,将变量的和形参名作为AO属性名,值为
undefined
AO{
a:undefined,
b:undefined,
}
- 将实参和形参统一
AO{
a:1,
b:undefined,
}
4.在函数体里面,找函数声明,值赋予函数体;
AO{
a:function a(){},
// 把形参覆盖了 注意:**function a(){} 是函数声明
只有它能提升; var b = function(){}这种是表达式**
b:undefined,
}
到此AO 对象创建完了
然后马上执行函数了 电脑从 AO 对象里面 拿东西
所以第一次打印的是function a(){},
a 被赋值123,第二次打印的是123,
然后因为function a(){}已经被提升上去,所以不用看,第三次打印也是123,第四次打印的function ({被提升,所以最后一次打印是function(){}}
// }
function test(a,b){
console.log(a); //function a(){};
console.log(b); //undefined
var b = 234;
console.log(b) //234
a = 123;
console.log(a); //123
function a(){};
var a ;
b = 234;
var b = function(){};
console.log(a); //123
console.log(b); //function(){};
}
test(1)
1. AO:{
//过程
}
2. AO:{
a:undefined;
b:undefined;
}
3. AO:{
a:1;
b:undefined;
}
4. AO:{
a:function a(){};
b:undefined;
}
所以第一次输出的a是 function a(){};b 是undefined
b=234
AO:{
a:function a(){};
b:234;
}
下个b输出就是234
a = 123
AO:{
a:123;
b:234;
}
下个a输出就是123
中间的声明对AO对象不产生影响所以输出不变
var b = function(){};
AO:{
a:123;
b:function(){};
}