javascriptfunction constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { funcs[i] = function () { return i; } } return funcs; } var funcs = constfuncs(); alert(funcs[1]()); funcs[1]() 这个是什么意思?
javascript
function constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { funcs[i] = function () { return i; } } return funcs; } var funcs = constfuncs(); alert(funcs[1]()); funcs[1]() 这个是什么意思?
如果你想得到你“想象中”的结果,需要用闭包。
这题里,你的每一个funcs[i]都声明了一个函数,但是函数都没有被立刻执行,而是排进了队列。
但是你的for循环是一直在执行的,等10个函数声明完毕,i也走完了,就是说i现在的值是10。
这时,你调用funcs[1]()去执行你之前声明的函数,因为现在i是10,所以理所应当的返回10。
funcs[1]()
如果你想得到“正确”的结果,需要用闭包改写:
function constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { funcs[i] = (function () { return i; }(i)) } return funcs; } var funcs = constfuncs(); console.log(funcs[1]);
用闭包保存i,这样你最后返回的值才会是你输入的值i。
这是个闭包的问题。funcs[1]是一个函数,返回的值是 i。funcs[1]() 就是运行这个函数。 对于外部 constfuncs来说,下面这个就是个闭包。
funcs[1]
constfuncs
javascriptfuncs[i] = function() { return i; }
funcs[i] = function() { return i; }
《JS高级程序设计》p.181 就是这个例子。
闭包保存的是整个对象,而不是特殊变量
每个funcs[n]里面引用的都同一个变量 i ,所以最后的返回值是一样的。
我把题中的函数改了改,为了方便显示,i 就改成了3。楼主看图感受下,应该就明白了。
首先, funcs是生成了10个function对象的数组,每个节点都是一个
javascriptfunction () { return i }
function () { return i }
但这里有个bug,这里的i其实都是引用了var i;所以闭包里面i都是指向同一个i; 解决的话,需要一个自执行的方案,
javascriptfunction constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { funcs[i] = (function (e) { return e; })(i); } return funcs; } var funcs = constfuncs(); alert(funcs[1]());
function constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { funcs[i] = (function (e) { return e; })(i); } return funcs; } var funcs = constfuncs(); alert(funcs[1]());
我知道 let 也能解决。
let
javascriptfor (let i = 0; i = 0; i < 10; i++) { ... }
for (let i = 0; i = 0; i < 10; i++) { ... }
也能解决,不知道是不是所有浏览器都支持
回答的瞬间就有三个答案了
function constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { funcs[i] = (function (i) { return function(){ return i; }; }(i)) } return funcs; } var funcs = constfuncs(); console.log(funcs[1]());
闭包内捕获的变量是一个引用,而不是当时变量值的快照,相反的,函数参数中的参数传递传递的是变量的值。题目中的源代码里,闭包捕获到的是变量i的引用,始终指向变量i,i的值在循环式的最后变为了10,所以所有函数的返回值均为10。
以下代码就是一个返回当时变量i的值的快照的形式。在函数createFunc的参数传递中对变量i的值进行了拷贝。
function constfuncs() { var funcs = []; for (var i = 0; i < 10; i++) { function createFunc(i) { return function() { return i; }; } funcs[i] = createFunc(i); } return funcs; } var funcs = constfuncs(); alert(funcs[1]());
这就是个闭包呀,犀牛书上的例子。 var funcs = constfuncs(); constfuncs()运行这个函数,并将return结果返回给funcs。 过程:1. 新建数组,同时for循环生成一个函数数组。每个函数数组中属性都是function(){return i}; 2. for循环结束。此时i=10. 3. rerurn 这个函数数组给funcs。此时funcs是一个函数数组。 注意:第一步中,循环只是把这些函数function(){return i}放进数组中,这些函数本身是没有运行的。 第三步是funcs是这个函数数组的外部引用,所以,constfuncs这个函数的作用域对象,没有当做垃圾被回收。 alert(funcs[1]()); 过程: 1.运行这个函数数组中第二个函数, 此时function(){return i} 2.在运行function(){return i}时。i的循环已经结束了。而且i的值为10.所以此时运行结果就是返回一个数字10。
funcs是一个数组,数组元素个数为10个,每个元素都是函数
function () { return i; //for循环完结后,i的值为10. }
funcs[1]表示第一个元素,即以上的函数 funcs[1]()表示执行函数。函数返回值为10,所以输出10
考察了闭包的概念
内部funcs[i]形成闭包,与循环构成异步,循环瞬间执行完,内部的闭包待循环执行完之后才拿到值,当然就是10咯
如果你想得到你“想象中”的结果,需要用闭包。
这题里,你的每一个funcs[i]都声明了一个函数,但是函数都没有被立刻执行,而是排进了队列。
但是你的for循环是一直在执行的,等10个函数声明完毕,i也走完了,就是说i现在的值是10。
这时,你调用
funcs[1]()
去执行你之前声明的函数,因为现在i是10,所以理所应当的返回10。如果你想得到“正确”的结果,需要用闭包改写:
用闭包保存i,这样你最后返回的值才会是你输入的值i。
这是个闭包的问题。
funcs[1]
是一个函数,返回的值是 i。funcs[1]()
就是运行这个函数。对于外部
constfuncs
来说,下面这个就是个闭包。《JS高级程序设计》p.181 就是这个例子。
每个funcs[n]里面引用的都同一个变量 i ,所以最后的返回值是一样的。
我把题中的函数改了改,为了方便显示,i 就改成了3。楼主看图感受下,应该就明白了。
首先,
funcs是生成了10个function对象的数组,每个节点都是一个
但这里有个bug,这里的i其实都是引用了var i;所以闭包里面i都是指向同一个i;
解决的话,需要一个自执行的方案,
我知道
let
也能解决。也能解决,不知道是不是所有浏览器都支持
回答的瞬间就有三个答案了
闭包内捕获的变量是一个引用,而不是当时变量值的快照,相反的,函数参数中的参数传递传递的是变量的值。题目中的源代码里,闭包捕获到的是变量i的引用,始终指向变量i,i的值在循环式的最后变为了10,所以所有函数的返回值均为10。
以下代码就是一个返回当时变量i的值的快照的形式。在函数createFunc的参数传递中对变量i的值进行了拷贝。
这就是个闭包呀,犀牛书上的例子。
var funcs = constfuncs();
constfuncs()运行这个函数,并将return结果返回给funcs。
过程:1. 新建数组,同时for循环生成一个函数数组。每个函数数组中属性都是function(){return i};
2. for循环结束。此时i=10.
3. rerurn 这个函数数组给funcs。此时funcs是一个函数数组。
注意:第一步中,循环只是把这些函数function(){return i}放进数组中,这些函数本身是没有运行的。
第三步是funcs是这个函数数组的外部引用,所以,constfuncs这个函数的作用域对象,没有当做垃圾被回收。
alert(funcs[1]());
过程: 1.运行这个函数数组中第二个函数, 此时function(){return i}
2.在运行function(){return i}时。i的循环已经结束了。而且i的值为10.所以此时运行结果就是返回一个数字10。
funcs是一个数组,数组元素个数为10个,每个元素都是函数
funcs[1]表示第一个元素,即以上的函数
funcs[1]()表示执行函数。函数返回值为10,所以输出10
考察了闭包的概念
内部funcs[i]形成闭包,与循环构成异步,循环瞬间执行完,内部的闭包待循环执行完之后才拿到值,当然就是10咯