If:
var x = [1, 2, 3];
var y = [4, 5, 6];
var z = x;
and then if z[2] = y[0];
Why is it that console.log(x); is [1, 2, 4] and not [1, 2, 3]?
When you do var z = x; you are no creating a new array, entirely separate from x, you are simply creating a reference to the original array. Hence, the change happens in both.
If you want to create a new object, you can use the new ES6 spread operator
var z = {...x};
Have a look at this answer for a more in-depth explanation of passing by reference and by value.
Cuz the 'z' variable is a pointer to the same array that 'x' point to.
An array in JavaScript is also an object and variables only hold a reference to an object, not the object itself. Thus both variables have a reference to the same object. So changing made through one variable reflected in other as well.
var x = [1, 2, 3];
var y = [4, 5, 6];
var z = x;
z[2]=y[0];
console.log(x);
var w=Object.assign([],x);
w[0]=y[1];
console.log(x);
console.log(w);
Look at the example. If you want to change in a new variable and don't want reflected that change in original one than use Object.assign.
Related
If I do this:
a = []
b = [1, 2, 3]
a = b
a will then refer to b
I want to copy all of the values in b into a without changing any memory address/references.
You could push the values without changing the reference from a or b.
var a = [],
b = [1, 2, 3];
a.push(...b);
If you want to populate a in-place, without ever discarding the initial array, then you can simply loop over b and add all the items in a:
var a = []
var b = [1, 2, 3]
var firstA = a; //get a initial element
b.forEach(function(item) {
this.push(item)
}, a);// <-- pass `a` as the `this` context
console.log("`a` is unchanged", a === firstA);
console.log("`a` is not `b`", a !== b);
console.log(a);
let a = b.map(x => x);
The .map() function will create a new array with values generated from the source elements via the passed-in callback function.
As noted in a comment
let a = b.slice();
is pretty much exactly the same.
Basically this saves you the step of
let a = [];
since one brand-new empty array is as good as another. However, if you really have your heart set on using the empty array explicitly initialized, you could use
b.forEach(x, i) { a[i] = x; });
A= b.slice(). It will create a shadow copy of element without changing original one. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
I'm trying to delete max value from arMin and min value from arMax, but arr (is a const!) changes too! I don't know why. I am using Google Chrome version 65.0.3325.181.
'arr' is only one time declared and it shouldn't do nothing with that. I can't understand that. Tried with delete, but it's turning numbers into 'empty', but works the same and changes const too!
It's my first post, so if I do something wrong please forgive me.
const arr = [1, 2, 3, 4, 5];
let arMin = arr;
let arMax = arr;
let min = arMin.indexOf(Math.min.apply(null, arMin));
let max = arMax.indexOf(Math.max.apply(null, arMax));
arMin.splice(max, 1);
arMax.splice(min, 1);
console.log(arMin); // [2,3,4]
console.log(arMax); // [2,3,4]
console.log(arr); // [2,3,4]
The value of arr is a reference to an array.
You cannot change that. It will always be a reference to that array.
Arrays are mutable though, so you can change values in the array. const won't prevent that.
If you want arMin and arMax to be different arrays, then you need to make a copy of the array and not just copy the value of arr (which is a reference to that array).
const makes the reference constant, not the value.
You can't make arr point to something else, but you can change its values.
Note: other languages, Dart comes to mind, have the ability of specifying constant values. That's not the case of JavaScript.
When you make an array const then you can not change the reference
const arr = [1,2,3]
arr = [4,5,6] \\ Throws errors; You can not change const reference
arr[1] = 6; \\ Works fine. You are not changing the const reference. You are just mutating the array.
const x = 5; \\ Here constant is the value
x = x + 1; \\ Error. You can not change the constant value;
As a constant, you can't reassign its value, in this case, it contains the reference to the array.
But the array itself is not immutable.
An example would be:
const arr = [0,1,2,3,4,5];
arr = 'foo' // You cannot do that
arr.push(6) // That works fine. result: [0,1,2,3,4,5,6]
To complete previous answer, to make an exact copy of array instead of copying reference, you should do something like this :
const arr = [1, 2, 3, 4, 5];
let arMin = [...arr]; // We use spread operator to create new array from original one.
let arMax = [...arr];
let min = arMin.indexOf(Math.min.apply(null, arMin));
let max = arMax.indexOf(Math.max.apply(null, arMax));
arMin.splice(max, 1);
arMax.splice(min, 1);
console.log(arMin); // [1, 2, 3, 4]
console.log(arMax); // [2, 3, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5]
--- EDIT 1 ---
i use TypeScript synthax to illustrate type
const arr = [1, 2, 3, 4, 5];
arr.push(6); // Is allow.
const object: {id: number, title: string} = {id: 1, title: 'Yanis'};
object.id = 2; // Is allow.
const myString: string = 'yanis';
myString = 'Jackob'; // Not allow.
I've noticed that [].concat() performs similarly to angular.copy() with arrays. For instance,
var x = [5, 2];
var y = [].concat(x);
// y = [5, 2]
x = [2, 3];
// y = [5, 2]
var z = angular.copy(x);
// z = [2, 3];
x = [6, 9];
// z = [2, 3];
Is there a key difference between [].concat() and angular.copy(src,[dest])?
angular.copy performs a deep copy of the source and places it on the destination (Both the arrays of source and dest and its contents, even reference types, points to different reference location). But when you do [].concat (Both the arrays of source and dest points to different reference and its reference type contents points to the same reference), it just returns a new array, so only think that is similar in using both angular.copy and [].concact in your example is that it assigns a new reference of the array object to the lhs variable.
But consider the situation where you have array of objects.
$scope.arr = [{name:'name1'}, {name:'name2'}, {name:'name3'}, {name:'name4'}];
$scope.arrConcat = [].concat($scope.arr); //Get a new array
$scope.arrCopy = angular.copy($scope.arr); //Get a new copy
//Now change the name property of one of the item
$scope.arr[3].name="Test";
//Now see who all have been changed
console.log($scope.arr[3].name); //Of course will output "Test"
console.log($scope.arrConcat[3].name); //Will also output "Test" because the new array items still holds the same reference of the objects.
console.log($scope.arrCopy[3].name); //Will output name4 because this contains another reference which holds the copy of the value of the object at index 3 from source array
//Push something on to the original array
$scope.arr.push({name:'name5'});
//You will see that new item is not available here, which is exactly the behaviour that you are seeing in your case because both the arrConcat and arrCopy holds its own version of array through the items in arrConcat and arr are from the same reference.
console.log($scope.arrConcat);
console.log($scope.arrCopy);
So only thing is that in your case [].concat is kind of a convenient method to get a copy of the source array since your array just has primitives, so no issues.
Example - Demo
http://plnkr.co/edit/06zLM8g34IDBLUmPtwV2?p=preview
var x = [5, 2];
var y = [].concat(x);
// y = [5, 2]
var x = [5, [5, 2]];
var y = [].concat(x);
// y = [5, 2]
Check this out, [].copy() never does a deep copy unlike angular.copy()
I have put together a small test, can someone explain why does JavaScript do the following?
Why will testArr inherit the modifications of newArray?
var TestClass = function() {
this.testArr = [10,11];
this.addToArray = function() {
var newArray = this.testArr;
newArray.push(12);
}
}
var testClass = new TestClass();
testClass.addToArray();
console.log(testClass.testArr); // will be [10, 11, 12]
Because they're the same array. Variables contain references to arrays. You're assigning that reference to a new variable, and now both variables point to the same array.
Here's a much simpler test which reproduces the behavior:
x = [1, 2] // the value of x is a reference to an array
y = x // the value of y is a reference to the same array
y.push(3) // modify the array pointed to by both variables
console.log(x) // [1, 2, 3]
If you want to create a new array, you need to clone the array.
With following statement
var newArray = this.testArr;
You will not copy the values from inside testArr. You will create a reference to this array. When you make an adjustment to a reference you will automatically change the referenced source too.
When you want to copy the values from testArr to another variable you can do this instead.
var newArray = this.testArr.slice();
This will copy the values from testArr inside newArray.
I have an array: {r=1, g=4, b=6} How do i go about getting the value of each (r,g,b) into a separate variable?
JavaScript does not have associative arrays. So this is legal:
var my_rgb_arr = [1, 4, 6]
Or this can be legal:
var my_rgb_obj = { r: 1, g: 4, b: 6 };
To access the array:
my_rgb_arr[0]; // r
my_rgb_arr[1]; // g
my_rgb_arr[2]; // b
And the object:
my_rgb_obj.r; // r
my_rgb_obj.g; // g
my_rgb_obj.b; // b
Which are you dealing with?
That's not an array
That's almost an object constant, but you need ":" instead of "="
The values already are in separate variables, or would be if the syntax was OK
That's the syntax for instantiating an "object constant" and populating it with properties and values. If you assign that value (the whole thing) to another variable, then you'll be able to get at the properties.
var rgb = { r: 1, g: 4, b: 6};
var rByItself = rgb.r;
In Javascript, {r:1, g:4, b:6} would be an object. Let's pretend your object is declared as such:
var obj = {r:1, g:4, b:6};
Then you could retrieve the values of r, g, and b in two ways.
Method 1:
var red = obj.r;
var green = obj.g;
var blue = obj.b;
Method 2:
var red = obj['r'];
var green = obj['g'];
var blue = obj['b'];
What you have: {r=1, g=4, b=6} could only be interpreted as a block in ECMAScript. It is therefore not an Array.
Arrays and Objects Example:
var myArray = [1, 4, 6];
var myObject = { r:1, g:4, b:6 };
Block Example:
var r, g, b;
if(true)
{r=1, g=4, b=6};
Code should be executable, as transmitted and the outcome of that code posted.