This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
node.js newbie here. I'm looping through an array of objects, and setting a timeout for doing some ops using each object individually, the timeout for each objects also depends on some key-value within the object. The code is here:
for (var idx in arr) {
var obj = arr[idx];
interval = obj['key'];
setTimeout(function(){my_func(obj);}, interval);
}
Now what is failing here is that whenever a timeout occurs and the code block for my_func is called, it always acts on the last object in the array, probably because the variable 'obj' at that time points to it. How do I get around this? I am guessing I need a pass by reference, or something similar. Please point me in the right direction if I'm missing something here.
You will need to use closure for this:
for (var idx in arr) {
var obj = arr[idx];
(function( obj ){
interval = obj['key'];
setTimeout(function(){my_func(obj);}, interval);
})( obj );
}//for()
Related
This question already has answers here:
How to destructure into dynamically named variables in ES6?
(6 answers)
"Variable" variables in JavaScript
(9 answers)
Closed 1 year ago.
I understand this is a very dumb question, I am dumb, maybe confused.
Let us say that I have a module foo.js that after doing works returns an object like this bellow,
return {something, anotherThing, yetAnotherThing};
Now, I want to get those in my bar.js and work with, but not with all of them. Maybe sometimes with something and sometimes with anotherThing etc. So, what I do is,
const foo = require('../foo.js')
const { something } = foo()
Then I work with something in my files.
The problem here is, most of the time, I need something or anotherThing on a random basis. Like I do not know which one I will need. Sometimes I need all of them and somethings I need only one or two.
So, is it possible to write a function that dynamically gets the destructed variables and work with them? For example, if I create an array of the things needed from the foo file and pass that array to a function that takes element from the array to get variable from foo.js and work with it? An incorrect code example of what I am saying will be,
const iAmWrong = ( arr) => {
for (let i = 0; i < arr.length; i++) {
const { arr[i] } = foo();
}
arr[i]();
};
There must be a way to achieve this right? Maybe not how I am thinking it is in code but I hope it is not impossible.
Please help.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I have this array:
var arr = [];
var i =
1) There:
setInterval ( function push(arr) {arr.push(i+1)} , 5*1000)
you're shadowing the arr variable (that is declaring a new variable which hides the external one). You're thus pushing to undefined. There's of course the same problem when you read the values.
2) If you always push i+1 you always push 1. You probably want i++
Simply do
setInterval ( function push() {arr.push(i++)} , 5*1000)
This question already has answers here:
JavaScript Function Context Incorrect
(3 answers)
Closed 7 years ago.
I have a variable a that can be either an object or an array of objects. I have an array array.
I want to append a to array, so I thought of using either Array.prototype.push.call or Array.prototype.push.apply with a ternary operator as follows:
var a = "hello"; // or var a = ["hello", "world"];
var array = [];
var append = ($.isArray(a)) ? Array.prototype.push.apply : Array.prototype.push.call;
append(array, a); // Uncaught TypeError: undefined is not a function
($ being jQuery)
I'm new to JavaScript and I guess there is a good reason why this doesn't work but I couldn't find it. Can't apply or call be assigned to a variable? (They are not real functions?) Or is something missing on the call to append()?
Note: I know I could do this with if/else but I'd rather like to understand why I can't assign these methods to a variable and call it.
Minor additional question: I want to do this because I get a from a JSON API and if I understand correctly, JSON can't contain arrays of one single object. Although I feel that what I'm trying to do must be very common, I also couldn't find how other developers deal with this. Is there a better way than testing whether a is an array or not and use apply() or not accordingly?
This happens because call and apply are instance methods. They are critical to the context object this.
Eventually you should execute append.call(Array.prototype.push, array, a) because call or apply need function push to be passed as this
You don't need any if, just use concat
var array = [];
var a = "hello"; // or var a = ["hello", "world"]
array = array.concat(a);
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 9 years ago.
I have some JSON data, and I'm trying to create classes and methods dynamically based on that data:
var classes = JSON.parse(data);
var classesObj = {};
for(var c in classes){
var methods = classes[c].methods;
var methodsObj = {};
for(var m in methods){
methodsObj[m] = function(args){
return methods[m].property;
}
}
classesObj[c] = methodsObj;
}
return classesObj;
But my problem is if I call something like
firstClass.firstMethod()
The property that is returned is actually from lastClass.lastMethod() I'm pretty sure it's an instantiation problem, but I just can't seem to figure out where to go from here.
The problem is that the anonymous variables (c and m) are bound to the same variable outside of the your anonymous function. See Javascript closure inside loops - simple practical example.
This question already has answers here:
Copy array by value
(39 answers)
Closed 9 years ago.
It's really strange, I'm modifying one of the arrays and the other one gets modified! I found no way of making it work other than typing two times the array. What can I do?
function test(a,b,c,d)
{
this.a=a;
this.b=b;
this.c=c;
this.d=d;
}
var data0=data=[[1,2,3,4],[5,6,7,8]];
function construct(constructor,args)
{
function F(){return constructor.apply(this,args);}
F.prototype=constructor.prototype;
return new F();
}
for(var i=0,l=data.length;i<l;i++)
{
data[i]=construct(test,data[i]);
}
console.log(data0);
http://jsfiddle.net/mageek/3GNMC/2/
You are referencing the same items:
var data0=data=[[1,2,3,4],[5,6,7,8]];
(and as a side note - here data ends up on the global object as it isn't really declared, only data0 is)
If you want to generate two different arrays with identical items you can do this:
var data0 =[[1,2,3,4],[5,6,7,8]];
var data = [];
data = data.concat(data0);
or
data = data0.slice(0);
JavaScript will not copy arrays upon data0=data assignment, instead it will point both variables to the same object in memory. You need to actually clone the array fully, for example:
var data0 = data.slice(0);