var y = "global"; 
function constructFunction() { 
var y = "local"; 
function A(){
return y;
}
return A;

alert(constructFunction()());  // 结果为local==================================================
var y = "global"; 
function constructFunction() { 
var y = "local"; 
return new Function("return y");  

alert(constructFunction()()); // 输出 "global" ======================
为何前者形成了闭包,后者没有?

解决方案 »

  1.   

    大概是  return new Function("return y"); 这个语句创造的匿名函数确实就是在包外的,原因不清楚。
      

  2.   

     return new Function("return y");  返回的只是一个对象。。而不是函数体
      

  3.   


    var y = "global";
    function constructFunction() {
    var y = "local";
    return new Function("return y");
    }
    var func = constructFunction(); //now:func = new Function('return y'); 即此时的y并没有解析
    alert(func()); //now alert(y)
      

  4.   

    JavaScript的解释器在每次开始执行一个函数时,都会为该函数创建一个执行环境, 运行不属于任何函数的JavaScript代码的环境使用的是全局对象。 这个环境一个重要的部分就是定义变量的对象。当一个函数被调用时,就会为他创建 一个调用对象并放置在作用域链中。当该函数退出的时候,调用对象会从作用域链中 移除,所以也就没有对他的引用,所以JavaScript的垃圾回收机制会把它所占的内存 释放掉。下一次调用该函数数时又重复以上步骤,所以普通函数的调用对象的值并不 会在内存中保存,每一次调用都重新定义。如下例子: 
    function a(){
      var o = 0;
      return o;
    }
    e = a();

    但是当该函数有嵌套函数时,情况就不同了,分为两种情况: 第一种时嵌套函数不在外部函数外被引用,此时只是函数只是内部调用,包含在外围函 数里面,并没有与外界打交道,所以当函数运行完退出时,嵌套函数的调用对象,外围 函数的调用对象都不再被引用,javaScript垃圾回收机制将他们从内存中释放。跟普通 函数没有什么区别,只是在函数里面又嵌套一个函数而已。 var c = null;
    function a(){
      var o = 0;
      function b(){
         o++;
         return o ;
      }
      return b();
     }
    c = a();


    第二种情况就是嵌套函数被外围函数以外的全局对象引用。如下面这种情况: 

    var c = null; //定义全局变量c
      function a(){ //定义函数a
      var o = 0; //定义函数a的局部变量o
      function b(){ //定义函数a的嵌套函数b
       o++; /引用外围函数a的局部变量o,并自加
      return o; //函数b返回o的值
     }
      return b; //函数a返回其嵌套函数b
    }
     c = a(); //将调用函数a的结果赋给了全局对象c,此时c = b
     c(); //调用c实际上就是调用函数a的内嵌函数b正常情况下一个函数的内嵌函数对外是不可见的,但是因为此时函数a已经将其内嵌函数当做返回值传了出来,
    所以外围对象也可以调用函数b了 该函数就是一个闭包 

    为什么会这样呢? 
    因为在这种情况下函数b的调用对象(调用对象的属性局部变量)并不会在在作用域链中被移除, 函数b的局部变量o一直存在内存中,以为全局变量d引用了函数c()调用对象,而c()引用b()调用 对象,所以o一直被引用。
    Function()构造函数的特殊之处: 
    Function()构造函数创建的函数并不适用词法作用域,相反,它们总是当做顶层函数一样来编译的。 例子:

    var y = 1;
    function constructFunction(){
      var y = 2;
      return new Function("return y");
    }

    如果是利用词法作用域此时应该输出2,但是由于Function()的特殊性,此时输出1。以上是我函数有关知识的总结,希望对楼主有用,有什么疑惑还可以继续交流 
      

  5.   

    楼主只需理解
    Function()构造函数变量作用域是全局的就可以了啊
      

  6.   

    其实就是“词法作用域”与“变量作用域”,请看下面两个例子例子1:var b = "1111";function fn(){
    var b = "2222";
    function fn1(){
    alert(b);
    }
    fn1();
    }
    fn();//2222
    例子2:var b = "1111";function fn(){
    var b = "2222";

    }function fn1(){
    alert(b);
    }fn();//1111
    因为词法作用域在词法分析的时候,也就是在定义函数的时候就创建了,所以它是根据定义该函数的当前作用域来创建的,而变量作用域,是在执行函数的时候创建。。
    明显,例子1,fn1在定义的时候,var b = "2222",例子2, var b = "1111";楼主的例子var y = "global"; 
    function constructFunction() { 
    var y = "local"; 
    return new Function("return y");  

    alert(constructFunction()()); // 输出 "global"  
    无限等于
    var y = "global"; function fn1(){
    return y;
    }
    function constructFunction() { 
    var y = "local"; 
    return fn1;  

    alert(constructFunction()()); // 输出 "global"  
    不同在于fn1只定义一次,而new Function("return y")再每次执行的时候都会重新定义,执行