标签:
1.
1 function f1(){ 2 var n=999; 3 nAdd=function(){n+=1} 4 function f2(){ 5 alert(n); 6 } 7 return f2; 8 } 9 var result=f1(); 10 result(); // 999 11 nAdd(); 12 result(); // 1000
首先要说的是,闭包是functional language里面的核心概念。
当出现高阶嵌套函数的时候,编译器会做closure convention闭包变换
,核心就是变量不在分配在stack上,而是分配在heap上。这就是为什么f1已经返回,但是n还能被+1的原因。
楼主给出的这个程序,实际上就是一个高阶嵌套函数。
1. 因为在函数里面有定义的函数,这是嵌套。pascal也是允许嵌套函数。
2. 高阶的原因是,函数可以所谓参数传递和返回,像我们熟悉的C语言。
但是当高阶和嵌套同时出现,就会造成麻烦,所以pascal和C都只能支持其中的一个。
我来分析一下这个程序的执行流。
1. var result=f1(); 返回了一个函数f2, 因此result为f2。这个高阶函数特性,参考C语言函数指针。
2. result(); 调用f2,显然输出999.
3. nAdd(); 这里需要注意,这个nAdd实际上在定义的时候是一个lambda,是一个匿名函数,功能是n+=1。定义时将这个函数赋值给nAdd。所以在此时,实际上是调用了n+=1.为什么能找到n?因为n在堆里面。
4. result(); 调用f2,显然输出1000.
最后一点,n在堆上如何被销毁,这个工作是垃圾收集器负责。当n不在被任何闭包的env引用的时候,会被回收。
SF参考链接:http://segmentfault.com/q/1010000002880935?_ea=223108
1.
1 var x= 0; 2 var f=function(){ 3 x=1; 4 }; 5 f(); 6 alert(x); //1 7 function f(){ 8 x = 2; 9 } 10 f(); //1 11 alert(x);
等价代码:
var x; var f; function f(){ x=2; } x=0; f=function(){ x=1; }; f(); alert(x);//1 f(); //1 alert(x);//1
函数表达式不存在声明提前
SF:http://segmentfault.com/q/1010000002886791/a-1020000002886944 http://segmentfault.com/q/1010000002883076
标签:
原文地址:http://www.cnblogs.com/michael-xiang/p/4562297.html