首页 > 试题广场 > 请问以上程序的输出是()
[单选题]
function Foo(){
     var i=0;
     return function(){
         document.write(i++);
     }
}
var f1=Foo(),
f2=Foo();
f1();
f1();
f2();
请问以上程序的输出是()
  • 010
  • 012
  • 000
  • 011
推荐
答案:A
这是一个闭包,闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 
这里的局部变量i,对f1()来说是全局变量,对f2()来说也是全局变量,但是f1()的i跟f2()的i又是相互独立相互不可见的,f1()每执行一次,f1()的i就加一,f2()每次执行一次,f2()的i就加油,但是相互之间不影响,因此结果是010
编辑于 2015-01-28 10:08:55 回复(24)
1.当函数被创建时,内部[scope]属性被存储,在这个属性中保存一个包含全局变量对象的作用域链。
2.当函数被调用时,会创建一个执行环境及相应的作用域链,argument和实参为其进行初始化。
这里f1()函数和f2()函数在调用时会创建两个执行环境,保存各自的变量对象,结果是没有关系的。而同一个函数在多次调用时返回值会被保存在同一个变量对象中。
发表于 2015-07-21 09:06:28 回复(5)
f1(),f2()分别创建了自己的执行环境,所以它们两个是相互独立的,执行之后都会返回一个匿名函数,这个匿名函数的作用域链被初始化为其包含函数的活动对象(这里也就是i)和全局变量对象,f1执行之后i并不会销毁,因为返回的匿名函数还要引用i,i仍然在内存中,所以执行两次之后i的值变成了1,而f2执行之后i为0
发表于 2016-07-26 17:24:38 回复(0)
++运算符的使用,放在数字后表示后增,即先执行再+1,这里就是先执行console.log(i)之后i再加1,所以f1执行第二次的时候i已经变成了1,自然就输出1了。
发表于 2017-09-01 00:49:09 回复(0)
function Foo(){
     var i=0;
     return function(){
         console.log(i++);
     }
}
var f1=Foo(),
f2=Foo();
f1();//return i=1 输出0
f1();//return i=2 输出1
f2();//return i=1 输出0
发表于 2017-06-15 16:22:44 回复(6)
f1,f2是独立的作用域 i++ 先执行后加,所以第一次为0第二次为1
发表于 2018-01-12 23:05:32 回复(0)
具体来说:
   第一步:因为f1=Foo(),
function Foo(){
     var i=0;
     return function(){
         document.write(i++);
     }
}
相当于 f1=function(){
    document.write(i++);//i++先用后加因此打印0
}
第二步:f1=Foo(),
    f1=function(){
    document.write(i++);//第二次调用这个函数,由于这个函数是在Foo内i被调用,垃圾回收机制没法实现,那么因为第一步的调用此时i=1;
}
第三步:f2=Foo()
   这是一个新的变量调用,前面的i已经被垃圾回收,因此i又是0了
发表于 2018-05-07 17:49:16 回复(1)
LYS头像 LYS
A,这是一个闭包,因为f1调用了两次,所以第二个是1
发表于 2015-04-03 19:04:35 回复(0)
首先Foo是一个函数,在函数内部声明的变量是局部变量,所以f1和f2访问的i是互补影响的变量i,其次后置++是先取值+所以f1第一次打印出的是0第二次打印出的是1而f2访问的i与f1无关,所以是0,如果此题把函数中的变量改成i=0答案会变成012
发表于 2018-08-02 19:11:52 回复(0)
没有人疑问,执行document.write()后会重写整个页面吗?为什么会是追加.
原因: 一个页面加载完毕文档就关闭了,此时如果document.write()就会打开文档,那么之前的页面就会重写.   原因是用document.close();使文档关闭,而后再写入就会重写,在close前则是追加  
发表于 2018-03-25 12:08:44 回复(0)
这题我面美团时,被问到过,确实是闭包问题。
发表于 2019-09-02 16:40:22 回复(0)
复制闭包及作用域
发表于 2019-08-13 23:45:09 回复(0)
补充一下,全面的大佬已说了,函数内部的局部变量 i 对 f1() 和 f2() 都是全局变量,当执行这条语句时:
returnfunction(){
         document.write(i++);
     }
相当于:
returnfunction(){
         document.write( i );    //此时打印出来的是 i = 0
            i++ ;                 // i = 1 ,这个并不会打印出来,而是下次再调用的时候就会打印这个 i = 1
     }
所以说,第二个 f1() ,打印的是 1,不会重新开始的原因是:闭包 i 保存在内存中没有被释放

发表于 2019-07-20 11:50:19 回复(0)
闭包形成的环境以及举例,MDN上解释的很清楚了,而且很多示例可参考。
发表于 2019-06-24 09:31:37 回复(0)

闭包条件:必须是两个函数,并且为相互嵌套关系,并且内部函数会使用外部函数的变量


发表于 2019-05-19 07:34:22 回复(0)
来说一下i++和++i, i++ ,先执行后赋值 ++i ,先赋值后执行
发表于 2019-04-11 18:07:46 回复(0)
注意题目是i++ 会先输出i再自增1。
发表于 2019-03-27 17:20:36 回复(0)
有谁给解答一下,谢谢! 每次调用Foo(),第一行那个var i=0不是每次都把i置零了吗?
发表于 2019-03-17 22:24:02 回复(0)
虽然产生了闭包,可以使用变量i,但是由于返回的是信用值,造成f1,f2 的地址指向不同,因此不是使用的同一个i
发表于 2019-01-25 23:26:55 回复(1)
1.当函数被创建时,内部[scope]属性被存储,在这个属性中保存一个包含全局变量对象的作用域链。
2.当函数被调用时,会创建一个执行环境及相应的作用域链,argument和实参为其进行初始化。
这里f1()函数和f2()函数在调用时会创建两个执行环境,保存各自的变量对象,结果是没有关系的。而同一个函数在多次调用时返回值会被保存在同一个变量对象中。
发表于 2019-01-18 10:02:24 回复(0)

i++ 返回原来的值,++i返回加之后的值

发表于 2019-01-07 21:01:04 回复(0)