首页 > 代码库 > javascript中函数的不同解析

javascript中函数的不同解析

<html>
<head>
<title>javascript的函数的生命周期</title>
<meta charset="utf-8"/>
<script type="text/javascript">
	/*
		javascript是所有语言中对函数生命周期处理最为复杂的语言之一
		而javascript的函数的生命周期取决于js解释器是如何解释我们编写
		的js代码,我们以例子来说明javascript解释器的对函数处理的原理
	*/
	//为了测试方便,我们先定一个输出函数(nodejs可以直接使用console对象)
	function print(str){
		document.write(str+"<br/>");
	}
	//我们先定义一个函数
	function func1(){
		return "felayman1";
	}
	//我们打印出函数返回值,很显然是felayman1
	print(func1());
	//下面我们对该函数进行重新定义后呢?上面的内容还是打印出felayman1么?显然不是
	function func1(){
		return "felayman2";
	}
	//我们继续输出该函数的返回值,很显然我们都可以预测到结果为felayman2
	print(func1());
	/*
		上面的例子实在是让人乏味,因为一眼就可以看出的内容,没有必要在这里
		说明什么,因为函数会被覆盖的,很好,我也是想说明这个问题,既然明白这
		个道理,那么对于我们使用Function()构造器和用var f =function(){};
		函数表达式所创建的函数一样,一旦我们重定义了某个函数,则前面的函数一定
		会被后面所写的函数所覆盖,事实上是这样的,可事实上也不是这样的.下面我们
		继续用具体的实例在分析,为了必要的解释,我还是重写了另外两者函数的写法
	*/
	var f = function(){
		return "felayman3";
	};
	print(f());//这里必然打印出felayman3
	//然后我们复写
	var f = function(){
		return "felayman4";
	};
	print(f());//这里会打印出felayman4
	/*
		写道这里,我们先看看结果,结果分别为felayman2,felayman2,felayman3,felayman3
		写道这里我很吃惊,为什么会出现这样的结果,为什么我们直接使用函数调用的时候,前面的函数
		会被后面的函数覆盖,但是使用函数表达式的函数却没有被覆盖呢?其实这里已经涉及到js解释器
		对函数的处理方式了。下面说说javavascript解释器对这两者函数的处理
		javascript解释器在解析程序的时候,会以块(或者段)为单位去逐块解释的,这个块就是我们所写的		  <script>标签包含的脚本,在一个块中解释器会优先去提取那些声明的变量和函数,作为预处理,放在
		一个临时表中,后面声明的变量或者函数都会被覆盖,因此不管你何处声明的变量或者函数,解释器在提		  取的时候,一旦发现重复,就会更改临时表中的对应的值,将重复的值覆盖。这是javascrpt解释器对
		那些在相同作用域中声明的变量或者函数的一种处理方式,但是这种方式却不针对函数表达式Function
		构造器.因此会出现上面的结果,尽管函数表达式被覆盖,但是在不同的阶段输出的值依然是不同的,大家
		可以去测试一下Function(),器结果会和函数表达式的结果一致,下面我们使用一个经典的例子在证明
		我们所要表达的.
	*/
	 function test(){
		return 1;
	}
	print("函数第一次被定义的时候调用:"+test());
	var test = new Function("return 10");
	print("函数第二次被定义的时候调用:"+test());
	var test = function(){
		return 100;
	};
	print("函数第三次被定义的时候调用:"+test());
	//继续上面的代码,知识修改其返回值
	 function test(){
		return 1000;
	}
	print("函数第四次被定义的时候调用:"+test());
	var test = new Function("return 10000");
	print("函数第五次被定义的时候调用:"+test());
	var test = function(){
		return 100000;
	};
	print("函数第六次被定义的时候调用:"+test());
	/*
		上面的代码非常经典,下面我们就去解释这段代码的执行顺序
		其执行结果分别为:1000,10,100,100,10000,100000,
		首先javascript会把声明的函数全部提取出来,即第一个定义
		的函数会被第四次定义的函数所取代,因此,当程序执行到:
		print("函数第一次被定义的时候调用:"+test());的时候,
		返回的结果是1000,然后程序会去执行剩下的代码,当遇到:
		var test = new Function("return 10");的时候,此时
		的test会保存Function()构造器函数返回的结果10,程序继续
		执行会打印出test()函数的返回值也就是10,因此第二个打印出
		的值是10,然后由通过函数表达式复写了构造器的函数,因此test
		又会指向新定义的函数单元,也会获取新单元返回的结果100,因此
		程序第三次输出的是100,同理,第四次定义的函数早已经被预处理
		提取到临时表中了,程序会去临时表查找该函数,去获取它的返回值
		发现是100,因此第四次输出也是100,然后第五次,第六次输出都是
		前面的函数被后面的函数覆盖,分别输出10000,100000.
		当我们分析上述代码之后,我们应该清楚javascript对三种不同定义
		函数方法的不同解析了,对于声明的函数,会被提取到临时表,二通过
		函数表达式和构造器方法,则会当作表达式,一直等到执行到该处的时候
		才回去解析它的内容,而这也是为什么下面的会产生不同的效果
	*/
	hello();//函数会执行
	function hello(){
		alert("hello");
	}
	//如果使用下面的方法,则会报错
	hi();
	var hi = function(){
		alert("hi");
	};
	
</script>
</head>
</html>