JavaScript对函数的解析机制

JavaScript对函数的解析机制是不同的:

对于使用function语句声明的函数,JavaScript解释器会在预编译期就解析函数,而对于匿名函数则直到执行器才按表达式运算进行解析。

示例一:

下面是使用function语句声明的两个同名函数f,声明之后马上进行调用,代码如下:

function f(){			//声明函数f
	return 1;			
}
alert(f());				//返回2
function f(){			//声明函数f
	return 2;
}
alert(f());				//返回2

如果按代码从上到下的一般执行顺序,则第一次调用函数应该返回1,第二次调用函数应该返回2。但是真是情况却并不是这样。原来,JavaScript解析器在预编译时就会把所有使用function语句声明的函数进行处理,如果发现同名函数,则后面的函数体会覆盖前面的函数体。所以,当在执行期时,就会看到两次调用函数f时,返回值为2。

示例二:

如果把第一个函数改为匿名函数,则会发现两次调用函数返回值都为1。

var f = function(){			//定义匿名函数f
	return 1;
}
alert(f());					//返回1
function f(){				//声明函数
	return 2;
}
alert(f());					//返回1;

对于function语句创建的函数,JavaScript解释器不仅对函数名按变量标识符进行索引,而且对于函数体也提前进行处理。于是,在预编译期,同名的变量被后来的同名函数所覆盖。但是,在执行期,第一行初始化变量f值为一个匿名函数,于是又覆盖了变量f在预编译建立的索引,即指向一个函数体。所以,两次调用函数最后都返回匿名函数的返回值1。

示例三:

如果把第二个函数改为匿名函数,则两次调用函数的返回结构又不相同。

function f(){				//声明函数
	return 1;
}
alert(f());					//返回1
var f = function(){			定义匿名函数
	return 2;
}
alert(f());					//返回2

这次返回值不同,与上面分析的原因是相同的。因为在第一次调用函数f时,它指向的还是在预编译期索引的声明函数体,当第二次调用函数f时,该变量f已经被匿名函数所覆盖。

示例四:

如果把两个函数都修改为匿名函数,则JavaScript在预编译期没有处理函数,仅是建立变量f的索引。当在执行期,才按顺序处理每一个匿名函数。

var f = function(){
	return 1;
}
alert(f());					//返回1
var f = funtion(){
	return 2;
}
alert(f());					//返回2

提示:JavaScript解释器在预编译期处理函数时,是按代码块分别执行的,也就是说每块JavaScript脚本是分开的,这样就可以避免在逻辑上出现混乱。所谓代码块,就是被<script>标签分隔的JavaScript脚本。

示例五:

把两个被声明的同名函数放在不同的代码块中,则在预编译时,不会出现相互覆盖。

//脚本1
<script>
	function f(){
		return 1;
	}
	alert(f());			//返回1
</script>
//脚本2
<script>
	function f(){
		return 2;
	}
	alert(f());			//返回2
</script>

但是,同处于一个文档中的JavaScript脚本,即使它们分别位于不同的代码块中,但是它们都属于同一个作用域,相互之间时可以通讯和调用的。

//脚本1
<script>
	function f(){
		return 1;
	}
	alert(f());			//返回1
</script>
//脚本2
<script>
	alert(f());			//返回1
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值