js笔记 二.函数作用域与预编译

函数定义方式

命名函数表达式

function abc(){
//…code
}

匿名函数表达式

var a = function(){
//…code
}
或者
var b = function demo(){
//…code
}

当我们使用匿名函数第一种形式时,a.name 会打印a
当我们使用第二种形式时,b.name会打印demo

函数的参数

函数的形参与实参数量可以不相等,可以通过arguments属性访问与修改某函数的形参

var t1 = 11,
    t2 = 22,
    t3 = 33;
function demo(a,b){
	console.log(a + " : " + arguments[0]);
	console.log(b + " : " + arguments[1]);
	console.log(arguments[2]);
	//将新参列表都*10
	for(var t in arguments){
          arguments[t] *= 10;
      }
      
	console.log(a + " : " + arguments[0]);
	console.log(b + " : " + arguments[1]);
	console.log(arguments[2]);
}
demo(t1,t2,t3);
console.log(t1,t2,t3);
/*
11 : 11
22 : 22
33
110 : 110
220 : 220
330
11 22 33
*/

预编译

1.一切未经声明就赋值的变量都归window所有

eg : a = 10
eg : var a =b = 10;

2.一切声明的全局变量都是window的属性

eg : var a = 123 ====> window.a = 123

Ao对象

我们所使用的函数就像一个个独立的小房间,房间内的物品不会与其他房间的人共享
这个房间就是Ao对象
js在实现对函数的预编译的过程其实也就是构建Ao对象的过程
预编译只会发生在函数执行的前一刻,如果函数一直不被执行,那么该函数的预编译不会发生

AO对象建立的过程

1.创建Ao对象
2.填入形参与声明的变量
3.将实参赋值给对应的形参
4.声明函数

笔试题练手
题目一.
function demo(a){
   console.log(a);
   var a = 123;
   console.log(a)
   function a(){}
   console.log(a)
   var b = function(){}
   console.log(b)
   function d( ){}
}
demo(1);

解析

(1)第一步:创建AO对象
AO{
}
(2)第二步:将形参与声明的变量写入AO,默认值为undefined
AO{
  a : undefined
  b : undefined
}
(3)第三步:将实参的值赋给形参
AO{
  a : 1
  b : undefined
}
(4)第四步:声明函数
AO{
   a : function//因为a已经存在了,所以覆盖掉了以前的值1
   b : undefined
   d :function
}
AO对象建立完毕以后开始执行函数中的代码
这个时候我们会发现有些代码是冗余的,js引擎会选择忽略掉它
function demo(a){
   console.log(a);
   //这条语句相当于 
   //var a;
   //a = 123;
   //而var a这一条语句就是对象的声明语句,在AO对象的第二步就已经执行过
   //所以引擎会省略掉var a;
   var a = 123;//被引擎转化为 a = 123;
   console.log(a)
   //这条语句是函数的声明,在AO对象建立的第4步已经执行过
   function a(){}//直接被引擎忽略掉
   console.log(a)
   //这条语句虽然给b赋值给了一个函数,但是不是函数的声明相当于一条赋值语句,
   //但是变量b已经被声明过,所以变量声明会被省略
   var b = function(){}//相当于b = function(){}
   console.log(b)
   function d( ){}//直接被引擎忽略掉
}

引擎实际执行的代码如下
demo(){
   console.log(a);//function a
   a = 123;
   console.log(a)//123
   console.log(a)//123
   b = function(){}
   console.log(b)//function b
}

答案

function a
123
123
function b




题目二.
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 : function
   c : undefined
   d : function
}

引擎对原有代码进行处理
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);
}

真正执行时的代码如下:
function test(a,b){
   console.log(a);//1
   c = 0;
   a = 3;
   b = 2;
   console.log(b);//2
   console.log(b);//2
}

答案

	1
	2
	2
Go对象

Go对象与Ao类似,不过Go对象是面向全局的,Go对象中会包含多个AO对象
可以将Go对象看出是一个有多个子女的父亲
它有一个大房子,里面划分了很多的小房间,它的孩子Ao就住在里面
Ao在发现自己的有些东西稀缺的时候就会向Go去要
但是Go对象没有一些东西时,不能向AO去要(毕竟父母也是要面子的嘛)

GO对象建立的过程

1.建立Go对象
2.填入变量声明
3.声明函数

题目三.
console.log(test);
function test(test)
   console.log(test);
   var test  = 234;
   console.log(test);
   function test(){}
}
test(1)
var test = 123;

解析

Go 建立过程
(1)建立Go对象
GO{

}
(2)声明变量
Go{
 test : undefined
}
(3)声明函数
Go{
 test : function
}


Go执行过程
console.log(test);//function
//建立 test的AO
test(1)//执行test
var test = 123;


建立 test的AO
(1)第一步:创建AO对象
AO{
}
(2)第二步:将形参与声明的变量写入AO,默认值为undefined
AO{
  test : undefined
}
(3)第三步:将实参的值赋给形参
AO{
   test : 1
}
(4)第四步:声明函数
AO{
   test : function
}

引擎转化代码
function test(test)
   console.log(test);
   var test  = 234;//省略var
   console.log(test);
   function test(){}//省略
}
真正执行时的代码如下:
function test(test)
   console.log(test);//function
   test  = 234;
   console.log(test);//234
}

答案

function 
function
234
题目四.
	a = 100
	function demo(e){
	   function e(){}
	   arguments[0] = 2;
	   console.log(e)
	   if(a){
	      var b = 123;
	      function c(){}
	   }
	   var c;
	   a = 10
	   var a;
	   console.log(b);
	   f = 123;
	   console.log(c);
	   console.log(a);
	}
	var a;
	demo(1);
	console.log(a)
	console.log(f)

解析

Go执行过程
(1)
Go{
	
}
(2)
Go{
	a : undefined
}
(3)
Go{
	a : undefined 
	demo : undefined 
}




demo函数预编译如下
(1)
AO{	
}
(2)
AO{
	a : undefined
	b : undefined
	c : undefined
	e:undefined
}
(3)
AO{
	a : undefined
	b : undefined
	c : undefined
	e : 1
}
(4)
AO{
	a : undefined
	b : undefined
	c : function
	e : function
}

demo函数执行过程如下
function demo(e){
	arguments[0] = 2; // e = 2;
	conso.log(e) //输出2
	if(a){
	 b = 123;
	}
	a = 10;
	console.log(b);// 输出undefined
	f = 123; //因为f未经声明就使用,所以f被挂载到GO上
	console.log(c);//输出function
	console.log(a);//输出10
}


整体代码执行过程
/*代码执行前Go对象为
Go{
	a : undefined 
	demo : undefined 
}*/
a = 100
/*预编译前Go对象为
Go{
	a : 100 
	demo : undefined 
}*/

demo(1);//对demo进行预编译

/*预编译后Go对象为
Go{
	a : 100 
	demo : undefined 
	f : 123
}*/

document.write(a);//输出100
document.write(f)//输出123

答案

2
undefined
undefined
10
100
123	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值