can i have two objects with the same property names? [duplicate] - javascript

This question already has an answer here:
Javascript object when setting property all properties with same name are set
(1 answer)
Closed 1 year ago.
whenever i try to change the first object in the array's y, all the other objects y properties in my array also change, is there any way to prevent this, or a way to add multiple objects to an array that share the same properties ?
i have been trying everything to fix this(i was creating a game that uses a similar array for bullets firing and whenever i changed the y property of the first item in my array all the other y properties in the array changed with it) and i thought that this might be the problem ?
var obj = {x:30,y:20};
var arr = [];
for(var i = 0;i<3;i++) {
arr.push(obj);
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);

You can fix this by defining an object inside of .push().
This creates a new object for each element of the array, instead of the array containing multiple references to the same object.
var arr = [];
for(var i = 0;i<3;i++) {
arr.push({x:30, y:20});
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);

In JavaScript, objects are stored in memory as pointers to the values inside the object. This is different to how primitive data types (int, char, etc.)
A good way to show this is to try printing out the object, vs printing out an int:
HTML:
<div id="anelementhere"></div>
<div id="anotherelementhere"></div>
JS:
var x = 5;
var obj = {x:30,y:20};
document.getElementById("anelementhere").innerHTML = x;
document.getElementById("anotherelementhere").innerHTML = obj;
JSFiddle: https://jsfiddle.net/d3ohpqqp/
You should be able to see something akin to:
5
[object Object]
Now, knowing this, what's stored in the array is NOT {{x:30, y:20}, {x:30, y:20}, {x:30, y:20}}, but {[object Object], [object Object], [object Object]}, which all point to ONE {x:30, y:20}
This is what makes all the y properties change after changing one. Now a simple solution, as #IrkenVader has shown is where you initialize the object when you put it into the array.
However, if for some reason you still want the original object outside of the array, this is another solution:
var obj = {x:30,y:20};
var arr = [];
for(var i = 0;i<3;i++) {
arr.push({x:obj.x, y:obj.y});
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);
JSFiddle: https://jsfiddle.net/9gzyr38x/

you are making a single obj and passing a reference to the same object, 4 times in your array
instead you could try creating new objects in each iteration:
var arr = [];
for(var i = 0;i<3;i++) {
arr.push({x:30,y:20});
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);
You could also look up the various ways to "clone" an object. angular, jquery and underscore all provide methods to do so, or you can check out How to clone js object?

As well as the answer #IrkenInvader gave, you can also use jQuery to very easily perform a deep-copy of an object:
var obj = {x: 30, y: 20};
var arr = [];
for(var i = 0; i < 3; i++) {
arr.push(jQuery.extend(true, {}, obj));
}
arr[0].y = 40;
document.write(arr[0].y + " " + arr[1].y);

Related

Javascript associative array how to map multiple strings to a number

Javascript newbie here. I currently have an associative array in the following format:
StringA: number,
StringB: number
Is it possible to map multiple strings to the same number? Something like this (some numbers may have a different number of Strings mapped to them):
StringA, StringB, StringC: number,
StringD, StringE: number,
StringF, StringG, StringH, StringI: number
Basically, I want holder to have the same value whether I write var holder = arr[StringA] or var holder = arr[StringC]. If it's not possible could someone point me in the right direction? Any help would be greatly appreciated!
You could use an object with a value for the object with multiple keys for one object.
Basically this creates a reference to the shared object. Then you could change the value inside of the object.
var temp = { value: 42 },
object = {
a: temp,
b: temp,
c: temp
};
console.log(object.a.value); // 42
object.b.value = 7;
console.log(object.c.value); // 7
Basically Js don't have associative array they are objects. Read this:
http://www.w3schools.com/js/js_arrays.asp
You need pointers to achive this, but JS not have pointers. But ther is a way to use pointers: use objects.
var assoc = [];
assoc["stringA"] = { value: 1};
assoc["stringB"] = assoc["stringA"];
assoc["stringC"] = assoc["stringA"];
assoc["stringD"] = { value: 10};
assoc["stringE"] = assoc["stringD"];
console.log("A: "+assoc["stringA"].value);
console.log("B: "+assoc["stringB"].value);
console.log("C: "+assoc["stringC"].value);
console.log("D: "+assoc["stringD"].value);
console.log("E: "+assoc["stringE"].value);
console.log("======== modify value ======");
console.log("\nModify A to 2")
assoc["stringA"].value = 2;
console.log("B: "+assoc["stringB"].value);
console.log("C: "+assoc["stringB"].value);
console.log("\nModify E to 20")
assoc["stringE"].value = 20;
console.log("D: "+assoc["stringD"].value);
console.log("E: "+assoc["stringE"].value);

Javascript is this feature built into JS? [duplicate]

This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Modifying a copy of a JavaScript object is causing the original object to change
(13 answers)
Closed 25 days ago.
In the code below you see that it recognises arrayi as array - i.
Is this system built into js? I was experementing and it didn't function when I wrote array(i) instead of arrayi. The question then extends beyond all to ask if you could do iarray, ariray, arrayii or array(i*i) (just want to figure out the syntax of how this works).
var array = []
var arrayAmount = prompt("Select number of array")
for (var i = 0; i < arrayAmount; i++) {
var arrayi = array
arrayi.push([prompt("Select name for array " + (i + 1)), ["sub-element 1", "sub-elemet 2"], ])
console.log(arrayi)
}
console.log(array1)
Edit: I checked if the code would work if the for loop declares its own arrays instead of copying another array. Turns out it did not work and declared arrayi as arrayi instead of array1 or array2
You're confusing several JS concepts. I'll make some assumptions to explain some things, but feel free to correct me and I'll adjust my answer.
I believe you meant to assign a value at a particular index in the array, but what you ended up doing is creating a variable arrayi that is a reference to array:
var array = [];
array[1] = "foo";
console.log(array); // [undefined, "foo"]
What you did instead was create a reference, which means two different variable names will evaluate to the same object/array:
var array = [];
var reference_to_array = array;
reference_to_array.push("foo");
console.log(array); // ["foo"]
console.log(reference_to_array); // ["foo"]
Your original question includes: "and it didn't function when I wrote array(i) instead of arrayi".
To which the answer is: array(i) should be changed to array[i] when working with arrays.
Instead of fixing your original issue, you ended up creating new variables.
To fix your original code:
var array = [];
// Added parsing to an integer
var arrayAmount = parseInt(prompt("How many items do you want to add to the array?"));
for (var i = 0; i < arrayAmount; i++) {
// Method 1: directly access the index
//array[i] = [ prompt("Select name for array " + (i + 1)), ["sub-element 1", "sub-element 2"] ];
// Method 2 (Recommended): push a new element onto the end of the array
array.push([ prompt("Select name for array " + (i + 1)), ["sub-element 1", "sub-element 2"] ]);
// Log this element
console.log(array[i]);
}

$.each() over Key value pair array

I've created my array as following:
var test = [];
test['pizza'] = 4;
test['pudding'] = 6;
I'm used to use $.each to loop over my array and print out the values and indexes. I'm doing this as following:
$.each(test, function (index, value){
console.log(value);
});
Yet somehow it does only print [].
How would one loop through an array as mine to print out the values 4 and 6?
each will only iterate over iterable properties of the array, pizza and pudding are not iterable properties.
As you require the key-value pair, declare the variable as object.
var test = {};
test['pizza'] = 4;
test['pudding'] = 6;
You don't need jQuery to iterate through a Javascript array, just use for.
var test = [];
test['pizza'] = 4;
test['pudding'] = 6;
for (var k in test) {
if (test.hasOwnProperty(k)) {
console.log('Key: ' + k + ' Value: ' + test[k]);
}
}
// Key: pizza Value: 4
// Key: pudding Value: 6
You don't need to declare test as an object for this (suggested in other answers), array is fine.
By using for you are improving performance of your application. See here.
In both Firefox and Chrome, the for loop is well over 100x faster than
the others.
you might want to choose what happens to serve your needs. I guess you were trying to get a array of objects which will look something like [{},{},{},{}]
Here test is an object(Associative array), not an array so you need to declare it as javascript object
var test = {};
test['pizza'] = 4;
test['pudding'] = 6;
$.each(test, function (index, value){
console.log(value);
});

Working with associative arrays in javascript

I want to use a variable as index of my associative array
var usersName = []; // Just defining
userName[socket.id] = socket.name; // socket.id is an alphanumeric string
I want to use that socket.id(string) as the custom index of usersName array, so I can get a list of all the users connected to the socket. The problem is the way I'm escaping the variable ( I guess).
I've tried this but didn't work:
usersName ['\''+socket.id+'\''] = socket.name;
This works in PHP but, I just can't get it to work in javascript
Thanks for the help.
What you are trying to do is essentially this:
// say socket = {id: 123, name: 'Bob'};
var foo = {}; // create an object
foo[socket.id] = socket.name; // put socket.name under foo.
var i;
for (i in foo) { //loop through list
console.log(i, "is", foo[i]); //123 is Bob
}
right? Like the comments posted, JS doesn't have "associative arrays" but instead something better- psuedo-classical objects. Objects in JavaScript are nothing like those in PHP. You need to relearn what an "object" means when learning JavaScript. Arrays in javascript are not something to be proud of.. They are essentially just objects extending the Array prototype and with a special 'length' property. Arrays in JS also allow you to get data in order, by performing a for(i =..; i..; i +=..) loop. Other than the benefits of Array.prototype and the ability to load a list of things in some reliable order, arrays are not that special.
Hopefully this will work the way you want it. It's kind of PHP style:
1
var usersName = new Object();
usersName["123"] = 'Jane';
usersName["923"] = 'Charles';
for (var key in usersName) {
console.log(key + ' => ' + usersName[key]);
}
2
var usersName = {
'123' : 'Jane',
'923' : 'Charles'
};
for (var key in usersName) {
console.log(key + ' => ' + usersName[key]);
}

Difference between Array.length = 0 and Array =[]?

Can some one explain the conceptual difference between both of them. Read somewhere that the second one creates a new array by destroying all references to the existing array and the .length=0 just empties the array. But it didn't work in my case
//Declaration
var arr = new Array();
The below one is the looping code that executes again and again.
$("#dummy").load("something.php",function(){
arr.length =0;// expected to empty the array
$("div").each(function(){
arr = arr + $(this).html();
});
});
But if I replace the code with arr =[] in place of arr.length=0 it works fine. Can anyone explain what's happening here.
foo = [] creates a new array and assigns a reference to it to a variable. Any other references are unaffected and still point to the original array.
foo.length = 0 modifies the array itself. If you access it via a different variable, then you still get the modified array.
Read somewhere that the second one creates a new array by destroying all references to the existing array
That is backwards. It creates a new array and doesn't destroy other references.
var foo = [1,2,3];
var bar = [1,2,3];
var foo2 = foo;
var bar2 = bar;
foo = [];
bar.length = 0;
console.log(foo, bar, foo2, bar2);
gives:
[] [] [1, 2, 3] []
arr.length =0;// expected to empty the array
and it does empty the array, at least the first time. After the first time you do this:
arr = arr + $(this).html();
… which overwrites the array with a string.
The length property of a string is read-only, so assigning 0 to it has no effect.
The difference here is best demonstrated in the following example:
var arrayA = [1,2,3,4,5];
function clearUsingLength (ar) {
ar.length = 0;
}
function clearByOverwriting(ar) {
ar = [];
}
alert("Original Length: " + arrayA.length);
clearByOverwriting(arrayA);
alert("After Overwriting: " + arrayA.length);
clearUsingLength(arrayA);
alert("After Using Length: " + arrayA.length);
Of which a live demo can be seen here: http://www.jsfiddle.net/8Yn7e/
When you set a variable that points to an existing array to point to a new array, all you are doing is breaking the link the variable has to that original array.
When you use array.length = 0 (and other methods like array.splice(0, array.length) for instance), you are actually emptying the original array.
Are you sure it really works?
I did a little experiment here, and trying to "add" an Array with a String resulted in a string.
function xyz(){
var a = [];
alert(typeof(a+$("#first").html()));
// shows "string"
}
http://www.jsfiddle.net/4nKCF/
(tested in Opera 11)

Categories