So I began to mess around with JavaScript today, and I came across a funny case where it seems convinced that something is a function while also convinced that it's not a function. This code illustrates the issue:
var arr1 = Array(1)
for (i = 0; i < arr1.length; i++) {
arr1[i] = function(n) { return n + i }
}
var arr2 = Array(1)
for (j = 0; j < arr2.length; j++) {
arr2[j] = function(n) { return arr1[j](n) }
}
typeof arr2[0] // "function"
arr2[0](2) // TypeError: Property '1' of object [object Array] is not a function
From here, you can assign a variable to arr2[0]
, and the error persists. I'm not sure if the closures or arrays are necessary to replicate this.
Is there something off with my code, or is this just one of those JavaScript oddities? This isn't something I particularly need an answer to, but it's a little silly so I'd like to know if there's a reason for it.
So I began to mess around with JavaScript today, and I came across a funny case where it seems convinced that something is a function while also convinced that it's not a function. This code illustrates the issue:
var arr1 = Array(1)
for (i = 0; i < arr1.length; i++) {
arr1[i] = function(n) { return n + i }
}
var arr2 = Array(1)
for (j = 0; j < arr2.length; j++) {
arr2[j] = function(n) { return arr1[j](n) }
}
typeof arr2[0] // "function"
arr2[0](2) // TypeError: Property '1' of object [object Array] is not a function
From here, you can assign a variable to arr2[0]
, and the error persists. I'm not sure if the closures or arrays are necessary to replicate this.
Is there something off with my code, or is this just one of those JavaScript oddities? This isn't something I particularly need an answer to, but it's a little silly so I'd like to know if there's a reason for it.
Share Improve this question asked Mar 26, 2013 at 4:09 user1392737user1392737 4-
1
Why
Array(1)
and a loop instead ofvar arr1 = [function(n) { return n + 1;}];
? – Matt Ball Commented Mar 26, 2013 at 4:14 - possible duplicate of Javascript closure inside loops - simple practical example – bfavaretto Commented Mar 26, 2013 at 4:15
- This originally occurred while I was experimenting with arrays of closures over loop indices, so I just kept it like that – user1392737 Commented Mar 26, 2013 at 4:19
- Also, @bfavaretto: that's something like what I was originally testing out, and it turns out it has more to do with this than I'd thought (in that the underlying principle of each is the same). So I'm willing to concede this to be a duplicate. – user1392737 Commented Mar 26, 2013 at 4:42
4 Answers
Reset to default 3This actually does have a bit to do with closures.
First, take this code:
for (j = 0; j < arr2.length; j++) {
arr2[j] = function(n) { return arr1[j](n) }
}
The variable j
initially holds the value 0, thus arr2[0]
is set to a reference to a function.
Next, j
is incremented, and now has a value of 1. This terminates the loop.
Now, when the function is called:
return arr1[j](n)
Due to closures, j
still has its final value of 1. Which is an invalid index in that array.
One more thing to point out. A for
loop doesn't create a new closure, so if you're expecting the anonymous function to enclose the value of j
within that iteration, that assumption is wrong. There will be a single instance of j
within the entire function that j
was declared in.
I think you are trying to make use of closure inside the loop, but it doesn't work like that.
If you want to work with the value of i
and j
in each step of the loop, you have make make use of an anonymous function as shown below.
var arr1 = Array(1)
for (i = 0; i < arr1.length; i++) {
arr1[i] = (function(i){
return function(n) {
return n + i
};
})(i);
}
var arr2 = Array(1)
for (j = 0; j < arr2.length; j++) {
arr2[j] = (function(j){
return function(n) {
return arr1[j](n)
}
})(j);
}
typeof arr2[0]
arr2[0](2)
Demo: Fiddle
It's not doing anything weird.
You're just trying to something that isn't a function (the value of arr1[1]
, which is undefined
).
It's probably safer to initialize arrays in the form:
var arr1 = [];
Or if you're using 'Array' you should initialize it like this:
var arr1 = new Array();
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745196867a4616137.html
评论列表(0条)