JS 预编译

JS 预编译

JS 运行三部曲:

  1. 语法分析
  2. 预编译
  3. 解释执行

预编译:

  • ** 暗示全局变量 ( imply global ):任何变量,如果未经声明就赋值,该变量即为全局对象 ( window ) 所有**
function test(){
	var a = b = 123;//先赋值b为123,声明a,再把b的值赋给a,b未声明就赋值,b为全局变量
}
window.a //undefined
window.b //123


  • 一切声明的全局变量,全是 window 的属性
var a = 123;

等价于:

window {
a : 123
}

所以,console.log(a) 是在 window 里寻找 a,即访问的是 console.log(window.a) = 123

function test(){
var a = 123;
}
test();
console.log(window.a);//undefined

预编译发生在函数执行的前一刻:

function fn(a){
	console.log(a);  //打印 AO 里面的 a : function a(){}
	var a = 123;  //预编译时 var a 已经提升,这里执行 a =123
	console.log(a);  //123
	function a(){}  //预编译时已提升,这里不再执行
	console.log(a);  //123
	var b = function(){}  //预编译时 var b 已提升,这里执行 b = function(){}
	console.log(b);  //function(){}
	function d(){}//预编译时已提升
}
fn(1);

具体过程:
1.创建 AO (Activation Object) 对象,即执行期上下文;

AO:{

}

2.找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined;

AO:{
		a : undefined,
		b : undefined
}

3.将实参值和形参统一;

AO:{
		a : 1,
		b : undefined
}

4.在函数体里面找到函数声明,将函数名作为 AO 对象的属性名,值赋予函数体;

AO:{
		a : function a(){},
		b : undefined,
        d : function d(){}
}

e.g.1

function test(a,b){
	console.log(a);  // 1 
	c = 0;
	var c;
	a = 3;
console.log(a);//3
	b = 2;
	console.log(b);  // 2
	function b(){}
	function d(){}
	console.log(b);	 //2
}
test(1);

预编译过程:
Step1 省略
Step2:

AO:{
	a : undefined,
	b : undefined,
	c : undefined,
}


Step3:

AO:{
	a : 1,
	b : undefined,
	c : undefined
}

Step4:

AO:{
	a : 1,
	b : function b(){},
	c : undefined,
    d : function b(){}
}

e.g.2

function test(a,b){
	console.log(a);  //functiona(){}一旦有重名的函数声明,必是函数体
	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);

预编译过程:
Step2:

AO:{
	a : undefined,
	b : undefined
}

Step3:

AO:{
	a : 1,
	b : undefined
}

Step4:

AO:{
	a : function a(){},
	b : undefined
}

全局的预编译:

1. 生成一个 GO (Global Object) 对象,GO === window;
2. 找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined;
3. 在函数体里面找到函数声明,将函数名作为 AO 对象的属性名,值赋予函数体

e.g.3

console.log(a);   //undefined
var a =123;

e.g.4

console.log(a);  //function a(){}
var a =123;
function a(){}

e.g.5

var a =123;
function a(){}
console.log(a);  //123
console.log(window.a);  //123

e.g.6

function test(){
	var a = b = 123;
	console.log(window.b);  //123 此时 GO:{b : 123}

	console.log(window.a);  //undefined   此时AO:{a : undefined}

}
test();

e.g.7

console.log(test);
					/*打印函数体 function(test){
						console.log(test);
						var test = 123;
						console.log(test);
						function test(){}*/
function test(test){
	console.log(test);//function test(){}
	var test = 123;
	console.log(test); //123
	function test(){}
}
test(1);
var test = 234;


全局预编译过程:

GO:{
test: function(test){
	console.log(test);
	var test = 123;
	console.log(test);
	function test(){}

}

test1() 执行前:

AO:{
test: function(){}
}

e.g.8

var glob= 100;
function fn(){
console.log(glob);
}
fn();//100

e.g.9

global = 100;
	function fn(){
		console.log(global);  //undefined
		global = 200;
		console.log(global);  //200
		var global = 300;
	}
fn();
var global;

e.g.10

function test(){
	console.log(b);  //undefined
	if(a) {
		var b = 100;
	}  // a 为undefined,if 不执行
console.log(b);  // undefined
	c = 234;
	console.log(c);  //234
}
var a;
test();
a = 10;
console.log(c);  //234

e.g.11

function bar(){
	return foo;  //等价于 console.log(foo);
	foo = 10;
	function foo(){}
	var foo = 11;
}
console.log(bar());   //function foo(){}

e.g.12

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值