how to assign an array by value to another variable javascript - javascript

i have an array channel_chunk
var channel = "global/private/user/updates/user_following/publisher_id/subcriber_id";
channel_chunk = channel.split("/"),
and i assign this array to another variable
var new_arr = channel_chunk ;
the problem is
when i changed
new_arr[0] = "test";
channel_chunk[0] also becomes test
so i think it is passed by reference when i am assigning , i want to assign channel_chunk by value to new_arr .
i know jQuery.extend will help. but i am using pure JavaScript in this case , so i can not use it , is there a built in function to do this in JavaScript . please help............

The "official" way to take a (shallow) copy of (part of) an array is .slice():
var new_arr = channel_chunk.slice(0);
[ It's called a "shallow" copy because any objects or arrays therein will still refer to the originals, but the array itself is a whole new copy. As you're using string primitives that won't affect you. ]

You will need to create a new array. An easy way to do this is simply concat with no args:
var new_arr = channel_chunk.concat();
Now modifying new_arr will have no effect on channel_chunk.

Related

Why does push of local array mutate global array?

I am puzzled why this following bit of code will return mutations of both the local and global array:
var globalarray = [1,2,3];
function test(){
let localarray = globalarray;
localarray.push(4);
console.log(localarray);
console.log(globalarray);
}
setInterval(test, 2000);
Returns:
[1,2,3,4] for both
My impression was that localarray would be a copy of globalarray. I saw another answer that said in order to make a copy of an array you need to use .slice().reverse(), which seems like a workaround. Why does it not just create a new local copy? Is there a simple and efficient way to make a local copy of a global array? Otherwise it seems like making multiple mutations to a global array is terrible for performance.
The reason for this in your code is because you are simply telling your test function to point to the globalarray with the = operator. This is because in JavaScript, variable assignments do not inherently "copy" objects into the new variables; this might seem confusing, so just think of the = operator as a sign that points your code to the location of an object.
The only times that the = operator is making new copies is when you are working with primitive types. In those cases, you cannot inherently change what those objects are, so = is sufficient to make a copy like you would expect.
The reason for the .slice().reverse() is to work around the problem you are seeing. Another way you could do this is by using let localarray = globalarray.map(e => e), or as samee suggested, by using let localarray = [...globalarray]. The .map operator takes the function given to it as the first argument and applies it to every element, and then it stores the result in a different array at another location that is not the same as globalarray.
Keep in mind that these methods, and any others that might be suggested to you, are shorthand ways of doing
let localarray = new Array(globalarray.length);
for (let i = 0; i < globalarray.length; i++) {
localarray[i] = globalarray[i];
}
// localarray can now be freely modified because it does not point to the same array as globalarray
Also keep in mind that if you need to also create copies of the elements inside of the arrays, then you will have to use more comprehensive copying code. There are libraries that can do this sort of heavy-duty copying if you really need it.
In JavaScript (as in many other languages), objects are passed by reference. Arrays are also passed by reference (because an array is actually a type of object). So when you say: let localarrray = globalarray, you are actually setting localarray to a pointer that resolves to globalarray.
There are several strategies for obtaining a true copy. If you're trying to get a fresh copy of the original array, the Array prototype function of .map() is one of the most targeted tools for the job. It would look like this:
let localarray = globalarray.map(element => element);
Simple way to clone an array is just
let localarray = globalarray.slice();
I do it a different way to deep cloning:
clone: function() {
var clone = undefined;
var instance = this;
if ( XScript.is.xobject(instance) ) {
clone = {};
for ( var prop in instance ) {
if ( instance.hasOwnProperty(prop) ) {
var p = instance[prop];
if ( XScript.is.xobject(p) ) p = p.clone();
clone[prop] = p;
}//END IF this
}//END FOR prop
return clone;
}//END IF xobject
if ( XScript.is.xarray(instance) ) {
clone = instance.slice(0);
return clone;
}
return clone;
}//END FUNCTION clone
This clone will require you attaching the clone object to the object prototype and check to see if its an array, object, or other. I am not changing the function to fit all your needs because one should learn to somewhat how to change it and what to do instead of copy pasta. Plus it is just an example.

Javascript Arrays - How do they work internally?

I wanted to know how javascript arrays work internally, I mean when for example you create a new array.
array = [1,2,3];
It's internally creating a new array: array = new Array();
and then calling Array.push() or similar?
Thanks.
The best resource to find out how javascript internals work is ECMAScript specification itself.
In order to understand what happens internally when you do array = [1, 2, 3] you would need to read section 7.3.16 CreateArrayFromList (elements). Roughly what happens is that first Array object gets created, then each element gets set to this object with CreateDataProperty (7.3.4 CreateDataProperty section) (DefineOwnProperty) internal method.
Then you want to learn what exactly happens when you push element to array. You check 22.1.3.17 Array.prototype.push ( ...items ) section for this. There you will find out that it uses quite different algorithm, namely it sets specific property of an object (7.3.3 Set (O, P, V, Throw) section).
So the answer is no, creating array like a = [1, 2, 3] does not uses same mechanics to insert items as push does. The first one roughly creates new property on (newly created) array object, the push sets property to existing object.
and then calling Array.push() or similar?
No. As you can see in the below example that when array is initialized push (overridden) method is not invoked.
Array.prototype.push = function(){ console.log("adding") };
var array = [1,2,3];
//console.log(array);
But, it is invoked when console statement is executed (after un-commenting the same).
var array = [1,2,3];
It doesn't call push but it's a simpler way to initialize an array when you know the elements in advance.
If you want to add another element you can do it in multiple ways like:
1) array.push(22); // adds integer 22 to the array
or
2) array[4] = 22; // adds integer 22 to the array at index 4
You can even do this:
array[20] = 22; // this will resize the array and keep all the uninitialized elements returns undefined. So array[10] is undefined, for ex.
If you want to know all the details about arrays explained in a simple way I recommend you the book: Secrets of the JavaScript Ninja. It has an entire chapter about arrays.
https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/1617292850/ref=sr_1_1?ie=UTF8&qid=1519484868&sr=8-1&keywords=javascript+ninja

Javascript array strange behaviour

By js convention and as far as I know
Primitive datatypes are worked under pass by value and
complex datatypes are worked under pass by reference
If it so
var ary = [1,2,3];
var dupAry = ary;
//Now I am going to rewrite the ary variable as follows
ary = [3,4,5];
Now I log the values of ary and dupAry it logs different values. By its standard both array should return the vaues.
so why it return different array values?
Another scenario
var ary = [1,2,3];
var dupAry = ary;
//No I gonna apply splice method to the ary.
ary.splice(0,1);
Now both array return same values and it works fine with its standard.
Finally why its doesn't applied with first scenario?
var dupAry = ary;
This assigns a reference to the array that ary points to to dupAry. Both ary and dupAry now hold a reference which points to the same array object. If you now assign something else to ary, then dupAry will continue to hold a reference which points to the array object, and ary will now hold some other value.
By assigning something to a variable, you're not modifying the object that variable already holds; you're modifying the object reference that variable holds.
ary.splice(0,1)
This modifies the actual object that both variables points to, so both see the change.
When you do this:
ary = [3,4,5];
... you aren't altering an array: you are destroying the previous reference and creating a brand new variable* with a brand new array. See the difference with:
ary.push(99);
(*) Well, not really a new variable, of course—I didn't know how to word it.

How to stop variables from connecting

Suppose you have the following code:
var array = [1];
var array2 = array;
array2.push(2);
alert(array);
This will alert "1,2", even though I clearly declared array as [1], and then did no changes to it. It's like array and array2 gets connected, and every change I do to array2 affects array. I simply want to declare array2 with the same value as array, not connect them.
Why does this happen and how to prevent it?
Thanks in advance!
jsFiddle
The problem is, that array2 is pointing on array.
what you want is:
var array2 = array.slice(0);
This really creates a copy of "array" and does not let the variable array2 point on "array".
It's because arrays and objects in JS are "passed by reference" (actually a copy of reference), not value (as it happens with primitives). There are many ways to do it, one of them being concatting an empty array:
var array = [1];
var array2 = array.concat([]);
array2.push(2);
alert(array); // 1
alert(array2); // 1,2
See some nice answers here: Does Javascript pass by reference?
Befor all , in Javascript an array is an Object
so the array variable is pointing to an in array (that you created [1]) that has an adresse in the memory (for example #1234abc). So the variable array it self is a pointer that points to an array.
You did var array2 = array
so array2 will point to the same adress in the memory (to the same object).
In other words, array2 is array they are pointing to the same object.
To get what you want, you have to create a new array and assign the same values of array1, this is called cloning.
You can do it with this trick var array2 = array.slice(0);
array2 is a reference to the original array, so if you modify it, the original will change too.
You´ll have to set array2's value to array.slice(), which clones the original and gives you a new reference.
It is because of concept Pass by reference. Internally both the variables are pointing to same memory location. So, when you change one variable that will effect other variables as well. Try slice() method if you intend to copy only values but not reference as it is. :)

Node/Javascript setting object property to array not working?

var arr = new Array();
arr[0] = "a";
var ob = new Object();
ob.prop = arr;
ob.prop[0] = "b";
//Console log arr[0] returns b
for some reason, the arr array is being changed when I change ob.prop ?
What am I missing?
As the system pointed out, ob.prop = arr is basically just giving another name for accessing the object referenced by arr. So when you modify ob.prop you are modifying the same object that arr also refers to.
EDIT: For copying an array take a look at this question:
var arrCopy = arr.slice();
As Jorge mentioned, this is happening because obj.prop is just a reference to arr, so arr and obj.prop will point to the same place in memory. So if you change either, the value in memory (which the other is pointing to) changes, thus changing both.
If you're looking to avoid this you need to do a deep copy. This will copy the values of the array into a new array, which obj.prop will point at.
There is a walk-through of how to do this in javascript here.

Categories

Resources