开发者

JavaScript recursion and closure?

I have this function (sample here: http://jsbin.com/emabe4/ )

var a=[];
var log = document.getElementById('log');

function loop(x){

  x++;
  a.push(x);

  if (x < 10){
    log.innerHTML = log.innerHTML + "<br/>" + a;
    console.log(a);
    loop(x)
  }

}

As the loop calls itself recursively, the array gets longer and is written out with the inner HTML as such:

[1]
[1,2]
...
[1,2,3,4,5,6,7,8,9]

Which is how I'd like it to work.

But if you look at the console log, this is what you see:

[1,2,3,4,5,6,7,8,9]
[1,2,3,4,5,6,7,8,9]
...
[1,2,3,4,5,6,7,8,9]

The questions:

1) Why the discrepancy between innerHTML and console.log?

2) the console log appears to be what is actually being created and I think that's due to a closure problem, correct? If so, what's the workaround for this to do what I want it to do (the former, where I can interact with the ar开发者_运维百科ray step-by-step as it grows each time)? I've solved this before in while loops, but not sure how to handle it here.


console.log(a) is should be strictly evaluated and will have the same results as the innerHTML. This can be verified (or disproved) with console.log("" + a). As the post and comments indicate, this differs by browser (Chrome is lazy here, Firefox is strict).

In the case of console.log("" + a) it forces the evaluation of the object in a to the string representation.

There is only one a in all cases (and more-so, there is only one array passed to console.log). That is, it's not a closure problem with the code, but rather a problem with console.log deferring conversion of the object to a string representation (in Chrome). If it defers conversion until after the loop completes then the behavior would be as described as it will print out the same object n (10) times in a row.

Happy coding.


Chrome console is keeping your array around and by the time it could display it, it already changed.

I guess that it might be filled as a chrome bug, that console.log should clone it's input or convert it to string but not defer evaluation of it's arguments.

By forcing a string conversion you could even get things like that :

a=1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3,4
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3,4,5
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3,4,5,6
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3,4,5,6,7
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3,4,5,6,7,8
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=1,2,3,4,5,6,7,8,9
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


The OP doesn't mention which browser this happening in, but this behavior has been reported in the Chromium project. See Issue 50316. A project member reports the following:

we evaluate array content asynchronously when it has its latest value

For other browsers this doesn't seem to be an issue.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜