今天阅读了一条代码,自己做了点分析,来分享下。
function f1(n){ if(n==0){return;} else{ return f2(-n); } } function f2(n){ alert(f1.caller); return f1(n); } f1(2);
结果大家可以跑一下,这里我想说的一点就是return的实际工作流程。
我们来看如下代码
function f1(){ alert(f1.caller); function f2(){ alert(f2.caller);//说明f2在f1的上下文中,调用f2,但f2并不是f1的方法,所以与之前书上解释不违背 alert(this);//window } f2(); } f1();//null,表示全局
翻开书,我们仔细阅读一下caller的用法,这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为null。
f2是在f1的上下文中声明的,并且f2也在f1的上下文环境中执行,因此,可以理解成时f1“调用”了f2.注意“调用”一词,f2实际上并不是f1的方法,这一点,我在new的那章已经说过,这样便导致了两个alert的结果。一个指向f2,一个指向全局。
再来一个代码
function f1(){ return function f2(){ alert(f2.caller);//window alert(this);//window } } f1()();
这里我们需要注意的是f2是在f1的上下文中被返回的,问题来了,这个f2的声明时在return之前了,还是在return之后了?
可能这个例子的结果还不是很有说服力,再来一段代码
function f1(){ return f2(); } function f2(){ alert(f2.caller); } f1();//f1中调用 f2();//window,return这个步骤我们需要留意一下
假设,return之后的东西,都是在return之后执行,按照这个思路,我们可以认为f1()和f2()是一个意思。但是结果却不是我们想要的。反过来,如果return之后的东西,是在return之前执行呢?
return f2()时,程序先在f1的上下文中调用了f2,所以f2.caller会是f1.如果直接调用f2,那调用者就是window,结果为null。ok,回到之前那个返回函数声明的例子中,这个声明依然是在f1的上下文中执行了,但是注意,它并没有在f1的上下文中调用它,看到执行语句f1()(),真正调用它的是全局对象。
现在,如果我们重新看一开始那段代码,也许就能很轻松的明白了。