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.
Related
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 closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I'm attaching elements created by Javascript inside a for loop.
What I'm trying to achieve is different variables passed to a function for each element.
Here's my code:
var thumbnail_box = document.createElement("div");
thumbnail_box.onmouseenter = function(){show_new_attachement_toolbar(total_upload)};
thumbnail_box.onmouseleave = function(){hide_new_attachement_toolbar(total_upload)};
the variable total_upload is automatically incremented in the end of each loop, however when all the elements are added, the function only triggers for the final value of total_upload instead of separate value for each element
A simple fix would be to wrap that code in an IIFE:
(function(x) {
var thumbnail_box = document.createElement("div");
thumbnail_box.onmouseenter = function () { show_new_attachement_toolbar(x) };
thumbnail_box.onmouseleave = function () { hide_new_attachement_toolbar(x) };
})(total_upload);
You might need to read this
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()
This question already has answers here:
How to execute a JavaScript function when I have its name as a string
(36 answers)
Closed 8 years ago.
I have an array with names of constructors var arr = ['Class1', 'Class2', 'Class3'].
function Class1() {
this.name = 'class1';
}
Is it possible to dynamically create instances of these classes? I mean something like
var class1Object = new arr[0]();
I tried that but it isn't working (Uncaught TypeError: string is not a function).
functions defined in "global" scope are actually created on the window object, so you can do this (as long as the code is in the head of the page, and not scoped to something specific):
function Class1(){
this.name = 'class1';
}
var className = "Class1";
var c1 = new window[className]();
Live example: http://jsfiddle.net/vdf4W/
Previously answered in this post (Google: Dynamic Instantiation In JavaScript)
Dynamic Instantiation In JavaScript
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);