JavaScript递归、预编译

JavaScript递归、预编译

1、JavaScript是解释性语言,执行三部曲如下所示

首先,js对代码进行语法分析,查看有无低级语法错误
然后,进行预编译
最后,解释执行,即解释一行执行一行

2、通用规律

函数声明整体提升,变量声明提升

  1. imply global暗示全局变量,即任何变量b,如果变量b未经声明就赋值,此变量就为全局对象所有,全局对象即为window.b可以在函数体外使用
    例如:

    function test() {
     	var a = b = 1;
     	console.log(a);
     	console.log(b);
     }
     test();
     console.log(b);
    

在这里插入图片描述
2. 一切在全局范围内声明的全局变量,全是window的属性
例如:

   var a = 1;

就相当于

   window.a = 1;

3、预编译

四部曲:

  1. 创建AO对象(即Activation Object,执行期上下文)
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
  3. 将实参值和形参统一
  4. 在函数体里面找函数声明,值赋予函数体
例子1:
function fn(a) {
	console.log(a);
	var a = 123;
	console.log(a);
	function a() {}
	console.log(a);
	var b = function () {}
	console.log(b);
	function d(){}
}
fn(1);

上面代码的预编译及执行过程如下

  1. 创建AO对象

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

    AO {
    		a : undefined;
    		b : undefined;
    }
    
  3. 将实参值和形参统一

    AO {
    		a : 1;
    		b : undefined;
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    AO {
    		a : f a() {};
    		b : undefined;
    		d : f () {};
    }
    
  5. 变量a已经提升声明,即在第2步已经优先声明,此处只需执行a = 123, b = f () {};

    AO {
    		a : 123;
    		b : f () {};
    		d : f () {};
    }
    

在这里插入图片描述

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

上面代码的预编译及执行过程如下

  1. 创建AO对象

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

    AO {
    		a : undefined;
    		b : undefined;
    		c : undefined;
    }
    
  3. 将实参值和形参统一

    AO {
    		a : 1;
    		b : undefined;
    		c : undefined;
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    AO {
    		a : 1;
    		b : f b() {};
    		c : undefined;
    		d : f d() {};
    }
    
  5. 变量a已经提升声明,即在第2步已经优先声明,此处只需执行c = 0; a = 3; b = 2;

    AO {
    		a : 3;
    		b : 2;
    		d : f () {};
    }
    

在这里插入图片描述

例子3:
function test(a, b) {
	console.log(a);
	console.log(b);
	var b = 234;
	console.log(b);
	a = 123;
	console.log(a);
	function a() {}
	var a;
	b = 234;
	var b = function () {}
	console.log(a);
	console.log(b);
}
test(1);

上面代码的预编译及执行过程如下

  1. 创建AO对象

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

    AO {
    		a : undefined;
    		b : undefined;
    }
    
  3. 将实参值和形参统一

    AO {
    		a : 1;
    		b : undefined;
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    AO {
    		a : f a() {};
    		b : undefined;
    }
    
  5. 变量a已经提升声明,即在第2步已经优先声明,此处只需执行b = 234; a = 123; b = 234; b = f() {};

    AO {
    		a : 123;
    		b : f() {};
    }
    

在这里插入图片描述

注意:

上述在函数体中,生成AO对象,而在全局状态下生成GO对象
window === GO,但能使用window.a,不能使用GO.a

例子4:
console.log(test);
function test(test) {
	console.log(test);
	var test = 123;
	console.log(test);
	function test() {}
}
test(1);

上面代码的预编译及执行过程如下

  1. 创建GO对象

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

    GO {
    		test : undefined;
    }
    
  3. 将实参值和形参统一

    GO {
    		test : undefined;
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    AO {
    		test : ƒ test(test) {
     			 		console.log(test);
     					var test = 123;
     					console.log(test);
     					function test() {}
     			};
    }
    
  5. 创建AO对象

    AO {
    
    }
    
  6. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

    AO {
    		test : undefined;
    }
    
  7. 将实参值和形参统一

    AO {
    		test : 1;
    }
    
  8. 在函数体里面找函数声明,值赋予函数体

    AO {
    		test : ƒ test() {};
    }
    
  9. 变量test已经提升声明,即在第2步已经优先声明,此处只需执行test = 123;

    AO {
    		test : 123;
    }
    

在这里插入图片描述

例子5:
global = 100;
function test() {
	console.log(global);
	global = 200;
	console.log(global);
	var global = 300;
}
test();
var global;

上面代码的预编译及执行过程如下

  1. 创建GO对象

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

    GO {
    		global: undefined;
    }
    
  3. 将实参值和形参统一

    GO {
    		global: undefined;
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    GO {
    		global: undefined;
    		fn : f () {
     		  	console.log(global);
     			global = 200;
     			console.log(global);
     			var global = 300;
     		 };
    }
    
  5. 创建AO对象

    AO {
     	
    }
    
  6. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

    AO {
    		global : undefined;
    }
    
  7. 将实参值和形参统一

    AO {
    		global : undefined;
    }
    
  8. 在函数体里面找函数声明,值赋予函数体

    AO {
    		global : undefined;
    }
    
  9. 变量global已经提升声明,即在第2步已经优先声明,此处只需执行global= 200; global = 300;

    AO {
    		global : 300;
    }
    

在这里插入图片描述

百度13年面试题
一、题目一
  1. 代码

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

上面代码的预编译及执行过程如下

  1. 创建GO对象

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

    GO {
    		
    }
    
  3. 将实参值和形参统一

    GO {
    		
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    GO {
    		bar : f () {
     				return foo;
     				foo = 10;
     				function foo () {}
     				var foo = 11;
     			  };
    }
    
  5. 创建AO对象

    AO {
     	
    }
    
  6. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

    AO {
    		foo : undefined;
    }
    
  7. 将实参值和形参统一

    AO {
    		foo : undefined;
    }
    
  8. 在函数体里面找函数声明,值赋予函数体

    AO {
    		foo : f () {};
    }
    
  9. 变量foo已经提升声明,即在第6步已经优先声明,此处只需执行return foo;

    AO {
    		foo : f () {};
    }
    

在这里插入图片描述

二、题目二
  1. 代码

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

上面代码的预编译及执行过程如下

  1. 创建GO对象

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

    GO {
    		
    }
    
  3. 将实参值和形参统一

    GO {
    		
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    GO {
    		bar : f () {
     				foo = 10;
     				function foo () {}
     				var foo = 11;
     				return foo;
     	};
    }
    
  5. 创建AO对象

    AO {
     	
    }
    
  6. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined

    AO {
    		foo : undefined;
    }
    
  7. 将实参值和形参统一

    AO {
    		foo : undefined;
    }
    
  8. 在函数体里面找函数声明,值赋予函数体

    AO {
    		foo : f () {};
    }
    
  9. 变量foo已经提升声明,即在第6步已经优先声明,此处只需执行foo = 10; foo = 11; return foo;

    AO {
    		foo : f () {};
    }
    

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值