【JS】这段代码不是很理解?为什么最后输出10

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]() 这个是什么意思?

回答

如果你想得到你“想象中”的结果,需要用闭包。

这题里,你的每一个funcs[i]都声明了一个函数,但是函数都没有被立刻执行,而是排进了队列。

但是你的for循环是一直在执行的,等10个函数声明完毕,i也走完了,就是说i现在的值是10。

这时,你调用funcs[1]()去执行你之前声明的函数,因为现在i是10,所以理所应当的返回10。

如果你想得到“正确”的结果,需要用闭包改写:

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来说,下面这个就是个闭包。

javascriptfuncs[i] = function() {

return i;

}

《JS高级程序设计》p.181 就是这个例子。

闭包保存的是整个对象,而不是特殊变量

每个funcs[n]里面引用的都同一个变量 i ,所以最后的返回值是一样的。

我把题中的函数改了改,为了方便显示,i 就改成了3。楼主看图感受下,应该就明白了。
【JS】这段代码不是很理解?为什么最后输出10

首先,

funcs是生成了10个function对象的数组,每个节点都是一个

javascriptfunction () {

return i

}

但这里有个bug,这里的i其实都是引用了var i;所以闭包里面i都是指向同一个i;

解决的话,需要一个自执行的方案,

javascript
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 也能解决。

javascriptfor (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咯

以上是 【JS】这段代码不是很理解?为什么最后输出10 的全部内容, 来源链接: utcz.com/a/87125.html

回到顶部