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>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。