
			<p>匿名函数的概念大家也许不会陌生，但是我相信下面的内容会打开一些新的思路。</p>
<p>我们知道函数的定义方式有两种：</p>
<blockquote><p>1 function fn1(){alert(&#8216;fn1 works&#8217;);}</p>
<p>2 var fn2=function(){alert(&#8216;fn2 works&#8217;);}</p></blockquote>
<p>这两种方式有什么区别？思考一下&#8230;</p>
<p>1 第一种方式定义函数，函数声明过程在整个程序执行之前的预处理就完成了，所以只要处于同一个作用域，就可以访问到，即使在定义之前调用它也可以。</p>
<p>2 第二章方式就是匿名函数，这种方式函数只能按照程序流程执行到定义的那一行代码才被声明，所以只能在定义之后调用它。</p>
<p>举个例子</p>
<blockquote><p>var fn1;</p>
<p>fn1();//报错</p>
<p>fn1=function(){</p>
<p>fn2();//fn2 works</p>
<p>alert(&#8216;fn1 works&#8217;);</p>
<p>return false;</p>
<p>function fn2(){</p>
<p>alert(&#8216;fn2 works&#8217;);</p>
<p>}</p>
<p>}</p>
<p>fn1();//fn2 works + fn1 works</p></blockquote>
<p>我们看到fn2虽然处在return之后，程序流程并没有执行到它，但是它依然可以被使用，反之fn2只有在它被定义之后才会被正常执行。</p>
<p>明白了这个，下面看一看匿名函数在递归里用处</p>
<p>递归就是函数内部调用自己，举个例子</p>
<blockquote>
<div>function fn1(n){</div>
<div>return n&gt;2?fn1(n-1)+fn1(n-2):n;</div>
<div>}</div>
</blockquote>
<p>当我们想把这个函数赋给其他的对象属性时，就要用到匿名函数，比如</p>
<blockquote><p>obj1={</p>
<p>fn:function(n){</p>
<div>return n&gt;2?obj1.fn(n-1)+obj1.fn(n-2):n;</div>
<div>}</div>
<div>}</div>
<div>obj2={</div>
<div>fn:obj.fn;</div>
<div>}</div>
</blockquote>
<div>这个时候可以正常调用obj2.fn()，但是这里有一个隐患，我们必须保证obj1里的fn不能被覆盖，看下面的例子</div>
<blockquote>
<div>obj1={}</div>
<div>obj2.fn();</div>
</blockquote>
<div>obj1被清空，执行出错，怎么办，解决办法有很多，自己先想一个&#8230;</div>
<div>最容易的想到的是使用this，更改obj1里面fn的定义如下</div>
<div>
<blockquote><p>obj1={</p>
<p>fn:function(n){</p>
<div>return n&gt;2?this.fn(n-1)+this.fn(n-2):n;</div>
<div>}</div>
<div>}</div>
</blockquote>
</div>
<div>这样即使obj1里的fn被改写也不影响obj2.fn()，但是this，你迷惑吗?</div>
<div>this在JavaScript里面绝对是一个难理解的概念，理解了最好，但是很多时候其实不一定非得用this，这个例子中，我们可以选个给匿名函数添加个名字</div>
<div>
<blockquote><p>obj1={</p>
<p>fn:function fnname(n){</p>
<div>return n&gt;2?fnname(n-1)+fnname(n-2):n;</div>
<div>}</div>
<div>}</div>
</blockquote>
</div>
<div>我们发现和this的结果一样，但是这就避开了this的混淆视听，而且注意这个函数名只有函数内部可以访问，外部是访问不了的(请私下测试)，这样就能避免诸如全局变量的问题。</div>
<div>还有一种解决方案，这个方案是最优雅的，所以我要作为大礼送给大家</div>
<div>我们知道有个arguments对象，这个对象里面有好多好玩的属性和方法，其中一个叫做callee，它的作用是调用函数本身！继续修改上面的例子</div>
<div>
<blockquote><p>obj1={</p>
<p>fn:function(n){</p>
<div>return n&gt;2?arguments.callee(n-1)+arguments.callee(n-2):n;</div>
<div>}</div>
<div>}</div>
</blockquote>
</div>
<div>这个是目前我发现最优雅的方法，大家有其他更好的方案可以拿来讨论。</div>
<div>匿名函数的讨论先到此为止。</div>
<p>转载请注明：<a href="#">大前端</a> &raquo; <a href="#">一家之言：谈谈JavaScript匿名函数</a></p>		