What's going on in the background with regard to this JavaScript? - javascript

I was reviewing some today, when I encountered the following convention :
TestParam(1);
function TestParam(p){
var p = p + 1;
alert(p); // alerts '2'
}
Now, obviously, the developer didn't mean to delcare 'p' within the function, instead maybe meaning:
p = p + 1;
But the code still worked, i.e. the value alerted was "2". So it got me to thinking. What would happen in the following scenario:
var a = 1;
TestParam(a);
alert(a); // alerts "1"
function TestParam(p){
var p = p + 1;
alert(p); // alerts '2'
}
Again the alerts were as I suspected (as intimated in the comments above). So then I was curious as to what would happen if I used an object:
var a = { b: 1 };
TestParam(a);
alert(a.b); //alerts 1
function TestParam(p) {
var p = {b:p.b + 1};
alert(p.b); //alerts 2
}
So, in this instance, JavaScript has 'remembered' the variable a, even though when it is passed to TestParam as p, p is redeclared.
Now if I were to have done the following within the function, then both alerts would have been "2"
p.b++;
//var p = {b:p.b + 1};
I.e. it would have modified the member b of the original object. I get this. Its the previous scenario that baffles me!
I realise this is quite a hypothetical question that is unlikely to carry much real-world usefulness, but it still made me quite curious, as to what is going on in the background, and how exactly JavaScript is scoping and referencing these variables.
Any thoughts?

Variables are scoped to the enclosing function in JavaScript. And you can declare them as many times as you like.
Objects are not tied to variables; many variables can refer to the same object. (This is sometimes called aliasing.) This is what's happening in your last example. JavaScript has not "remembered" the variable a at all; rather, p and a refer to the same object, so when it is changed via p, you can see those changes via a.
Here's an example that might make more sense to you. Sometimes a person has more than one identity.
var Clark = new Person;
var Superman = Clark; // Maybe not everybody needs to know these two are
// the same person, but they are.
Clark.eyes = "brown";
alert(Superman.eyes); // should be brown, right?
Knowing the rules of the language you're using has tremendous "real-world usefulness". Not understanding these two rules is the source of a lot of confusion and bugs.

Javascript generally passes all arguments to functions by reference except when the argument is a number or a string. Javascript passes numbers and strings by value which is why your first example works the way it does.

I believe there's a typo in your code. I think you mean:
function TestParam(p) {
var p = {b:p.b + 1}; // p.b, not p.a (p.a == undefined)
alert(p.b);
}
In your example:
var a = { b: 1 }; // "a" is defined in the global scope
TestParam(a);
alert(a.b); // alerts 1
function TestParam(p) {
var p = {b:p.a + 1}; // "p" is defined in TestParam()'s scope
/* But not until after the expression on the right side of the assignment
has completed--that's why you can use p.a
alert(p.a); //alerts 2
}
At first, "p" is passed as a reference to the global variable "a", but then you redefine it in the first line. So, for example:
var a = { b: 1 };
alert(a.b); // Alerts 1
TestParam(a);
alert(a.b); // Alerts 2
TestParam(a);
alert(a.b); // Alerts 3
function TestParam(p) {
p.b++;
}

Related

A rule for when variables get assigned to one another

Can I confirm that the reason code snippet 2 (&3) work is because something like: when variableA is fully, or partly, assigned to variableB, variableB always gets what variableA is at the time variableB is (last) initialised?
The aim: to make a function that continually prints "red0", "red1" "red2" etc.
In the first snippet, when we come to log out colorNum, colorNum doesn't dynamically update its num value. It's as if colorNum captures what num at the last moment colorNum was initialised.
num = 0;
colorNum = "red" + num;
function printObject() {
console.log(colorNum);
num++;
}
setInterval(printObject, 2000);
Here colorNum is continually reinitialised. So the updated value of num is captured in colorNum because colorNum is reinitialised after num is updated.
let num = 0;
let colorNum = "red" + num;
function printObject() {
colorNum = "red" + num;
console.log(colorNum);
num++;
}
setInterval(printObject, 2000);
Similarly the return expression of fun is a new expression every-time fun is called. The return expression captures the value of num at the point in time the return expression is created.
num = 0;
fun = function(){
return "red" + num;
}
function printObject() {
console.log(fun());
num++;
}
setInterval(printObject, 2000);
In languages like JavaScript (which is to say, most common programming languages), assigning a primitive value from one variable to another establishes absolutely no permanent relationship between them. The assignment operator is an immediate imperative, after which the two variables sail off into the night.
Also, note that the assignment
colorNum = "red" + num;
is evaluated by first computing the value of the right-hand side. The string constant "red" and the value of num are concatenated. After that has happened, before that result value is assigned, there is no remaining trace of num. All the runtime has is the result value from the concatenation, and that value has nothing whatsoever to do with the variable num.
Now, reference assignment is a different story, to some extent, or at least superficially, but as far as the language actually works it's the same story. So in
let x = { a: "hello" };
let y = x;
y.a = "goodbye";
console.log(x.a);
the value of property "a" in the only object involved will change. However, if subsequently:
let x = { a: "zebra" };
y.a = "giraffe";
console.log(x.a);
it'll still be "zebra" because assigning a new object reference to x has absolutely no effect on y.
From older languages like C, from which JavaScript syntax is at least loosely derived, an assignment expression is literally a request to copy a value stored in memory from one place to another. It looks like algebra but it does not work like pencil-and-paper algebra. JavaScript is conceptually a higher level language, but the semantics are still the same.
You're right in your assumption. In code snippet 2 and 3 num gets added every time. In 1 it is only added 1 time. At the moment of assignment the variable's value is taken. Whether it changes later doesn't matter.
Note that if you study Javascript a bit longer, you'll notice a different behaviour for Object and other types where assignment doesn't mean later changes to the original are disregarded, but this is a more advanced topic.
There is nothing like partial assignment; either you assign or don't assign.
In the first example, where you write colorNum = "red" + num;, you are not partially assigning num to colorNum. Rather you are using num in creating a new string, and then you are assigning that new string to the colorNum variable. So, as long as you don't update the colorNum with new value, it continues to hold the old value (As long as we are dealing with primitive values like numbers, strings, boolean, etc. This changes when we are dealing with objects which are usually passed around as references).
In example 2 & 3, you are updating the value of colorNum variable every time and hence they are working fine.
In your code examples there is no "magic" behind the variables assignment. The only difference is the order of commands.
Normally, all commands run synchronously, so one-by-one (we are not looking into parallel now). Of course, there are some differences between programming languages, for example in JavaScript all variable and function definitions (var) goes to the start of the code.
Let's return to your code.
Your first example:
num = 0;
colorNum = "red" + num;
function printObject() {
console.log(colorNum);
num++;
}
setInterval(printObject, 2000);
Actually it has var before variable creation. Also I will add line numbers, so it will be easier to understand the order of commands:
/* 1 */ var num = 0;
/* 2 */ var colorNum = "red" + num;
/* 3 */
/* 4 */ function printObject() {
/* 5 */ console.log(colorNum);
/* 6 */ num++;
/* 7 */ }
/* 8 */
/* 9 */ setInterval(printObject, 2000); // 9
First of all, functions and variables created, so first commands will be in line 1, 2, 4 (we create function, but do not run it, just create).
After command in line 1 we will have num equal to 0.
After command in line 2 we will have colorNum equal to "red" + num that is "red" + 0 that is "red0"
Now we come to line 9. Here we calling function printObject every 2 seconds, so...
...when 2 seconds passed we call function printObject, so:
we run command in line 5 and print to console our colorNum that is still equal to "red0"`
line 6 increase num by 1, so now we have num equal to 1
... another 2 seconds passed and we call function again, so:
we run command in line 5 and print to console our colorNum that is still equal to "red0"(because we did not change the value insidecolorNumafter it was set in line2`)
line 6 increase num by 1, so now we have num equal to 2
and so on... We print always the same colorNum as it was created on line 2 and we never change it again, so console.log will use its original value
Ok, now I will be quicker. Your second example has one additional line inside the function: colorNum = "red" + num;. That is very good, because now we change the value of colorNum before we print it to console.
Your third example has different idea of getting the value that we will print to console. You have added another function, that calculates the value. So your code:
num = 0;
fun = function(){
return "red" + num;
}
function printObject() {
console.log(fun());
num++;
}
setInterval(printObject, 2000);
Is equal to:
num = 0;
function printObject() {
console.log("red" + num);
num++;
}
setInterval(printObject, 2000);
This is because your function fun has only one line of code: "red" + num, so I can replace this function call with this line.
Actually, you even do not need to have a separate line for num++, or even the printObject can be "inlined":
var num = 0;
setInterval(() => console.log("red" + num++), 2000);

What is the use of just declaring variables

I have been using python for a while now, and have just started learning javascript. In javascript you can, as I understand it, declare a variable without assigning a value to it (var cheese compared to var cheese = 4) in what situation would you want to declare a variable but not assign a value to it straight away?
Consider this snippet.
if (someCondition) {
var x = 5;
} else if (someOtherCondition) {
var x = 4;
}
if (x) {
doFunc();
}
Since x needs to exist for the doFunc to run, you simply add an undefined declaration above. var x; so that the if (x) doesn't return an error.
You do this when you want the value of the variable to be undefined.
var cheese;
console.log(cheese); // undefined
It's simpler than
var cheese = undefined;
The undefined value doesn't seem much useful, but this will allow to assign some other value later.
var cheese; can be perfectly useful (even if you never assign anything to it). Of course it's a shorter way to type var cheese = undefined;, but that's not the only reason…
Using var declares a local variable, and this has a nice property: it hides variables from parent scopes.
There's another part to your question:
If we're going to assign a value to var cheese anyway: why not assign immediately?.
Answer: it may be fine for your algorithm to return cheese without ever assigning anything to it — i.e. "undefined is valid".
Here's an example which illustrates how var hides variables from parent scopes:
var a = 3;
console.log(a); // prints 3; "a" is defined in this scope
function findEvenNumber(numbers) {
var a; // we declare this local variable, to ensure that we do _not_ refer to the variable that exists in the parent scope
numbers.forEach(function(number) {
if (number % 2 === 0) {
a = number;
}
});
return a; // if no even number was found, it returns undefined (because we never assigned anything to a)
}
findEvenNumber([1, 2]); // returns 2;
console.log(a); // prints 3; the "a" in this scope did not get overwritten by the function
Speculation: maybe the var cheese; syntax exists in ECMA to enable programmers to declare all variables at the beginning of their function. Such a convention was enforced by the C89 compiler, and some people grew fond of it.

Use of setter and Object.create();

I'm currently reading the series of books You don't know JS. In one of the books it's written :
If a foo is found higher on the [[Prototype]] chain and it’s a setter
(see Chapter 3), then the setter will always be called. No foo will be
added to (aka shadowed on) myObject, nor will the foo setter be
redefined.
Now I tried the following code:
var a = {
set t(tet) {
this._t_ = tet;
},
get t() {
return this._t_ ;
}
};
a.t = 5;
var b = Object.create(a);
b.t = 4;
console.log(a.t);
console.log(b.t);
For my suprise the logs print out 5 and 4 in that order. From what is written in the book I expect to see two 4 being printed, but it seems there is actually shadowing. Why is that ?
Thanks to the answer by Quentin, this is actually the code that demonstrates the functionallity I wanted :)
var a = {
t : undefined,
set t(tet) {
t = tet;
},
get t() {
return t ;
}
};
a.t = 5;
var b = Object.create(a);
b.t = 4;
console.log(a.t);
console.log(b.t);
The 4 and 5 are stored in _t_ on the two different objects, not in t.
t is still the setter and getter in both cases (although the value of this varies because it is called in the context of two different objects).

Javascript Objects - Passed by Value or reference? [duplicate]

This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 3 years ago.
Does JavaScript pass by references or pass by values?
Here is an example from JavaScript: The Good Parts. I am very confused about the my parameter for the rectangle function. It is actually undefined, and redefined inside the function. There are no original reference. If I remove it from the function parameter, the inside area function is not able to access it.
Is it a closure? But no function is returned.
var shape = function (config) {
var that = {};
that.name = config.name || "";
that.area = function () {
return 0;
};
return that;
};
var rectangle = function (config, my) {
my = my || {};
my.l = config.length || 1;
my.w = config.width || 1;
var that = shape(config);
that.area = function () {
return my.l * my.w;
};
return that;
};
myShape = shape({
name: "Unhnown"
});
myRec = rectangle({
name: "Rectangle",
length: 4,
width: 6
});
console.log(myShape.name + " area is " + myShape.area() + " " + myRec.name + " area is " + myRec.area());
Primitives are passed by value, and Objects are passed by "copy of a reference".
Specifically, when you pass an object (or array) you are (invisibly) passing a reference to that object, and it is possible to modify the contents of that object, but if you attempt to overwrite the reference it will not affect the copy of the reference held by the caller - i.e. the reference itself is passed by value:
function replace(ref) {
ref = {}; // this code does _not_ affect the object passed
}
function update(ref) {
ref.key = 'newvalue'; // this code _does_ affect the _contents_ of the object
}
var a = { key: 'value' };
replace(a); // a still has its original value - it's unmodfied
update(a); // the _contents_ of 'a' are changed
Think of it like this:
Whenever you create an object in ECMAscript, this object is formed in a mystique ECMAscript universal place where no man will ever be able to get. All you get back is a reference to that object in this mystique place.
var obj = { };
Even obj is only a reference to the object (which is located in that special wonderful place) and hence, you can only pass this reference around. Effectively, any piece of code which accesses obj will modify the object which is far, far away.
My two cents.... It's irrelevant whether JavaScript passes parameters by reference or value. What really matters is assignment vs. mutation.
I wrote a longer, more detailed explanation in this link.
When you pass anything (whether that be an object or a primitive), all JavaScript does is assign a new variable while inside the function... just like using the equal sign (=).
How that parameter behaves inside the function is exactly the same as it would behave if you just assigned a new variable using the equal sign... Take these simple examples.
var myString = 'Test string 1';
// Assignment - A link to the same place as myString
var sameString = myString;
// If I change sameString, it will not modify myString,
// it just re-assigns it to a whole new string
sameString = 'New string';
console.log(myString); // Logs 'Test string 1';
console.log(sameString); // Logs 'New string';
If I were to pass myString as a parameter to a function, it behaves as if I simply assigned it to a new variable. Now, let's do the same thing, but with a function instead of a simple assignment
function myFunc(sameString) {
// Reassignment... Again, it will not modify myString
sameString = 'New string';
}
var myString = 'Test string 1';
// This behaves the same as if we said sameString = myString
myFunc(myString);
console.log(myString); // Again, logs 'Test string 1';
The only reason that you can modify objects when you pass them to a function is because you are not reassigning... Instead, objects can be changed or mutated.... Again, it works the same way.
var myObject = { name: 'Joe'; }
// Assignment - We simply link to the same object
var sameObject = myObject;
// This time, we can mutate it. So a change to myObject affects sameObject and visa versa
myObject.name = 'Jack';
console.log(sameObject.name); // Logs 'Jack'
sameObject.name = 'Jill';
console.log(myObject.name); // Logs 'Jill'
// If we re-assign it, the link is lost
sameObject = { name: 'Howard' };
console.log(myObject.name); // Logs 'Jill'
If I were to pass myObject as a parameter to a function, it behaves as if I simply assigned it to a new variable. Again, the same thing with the exact same behavior but with a function.
function myFunc(sameObject) {
// We mutate the object, so the myObject gets the change too... just like before.
sameObject.name = 'Jill';
// But, if we re-assign it, the link is lost
sameObject = {
name: 'Howard'
};
}
var myObject = {
name: 'Joe'
};
// This behaves the same as if we said sameObject = myObject;
myFunc(myObject);
console.log(myObject.name); // Logs 'Jill'
Every time you pass a variable to a function, you are "assigning" to whatever the name of the parameter is, just like if you used the equal = sign.
Always remember that the equals sign = means assignment.
And passing a parameter to a function also means assignment.
They are the same and the two variables are connected in exactly the same way.
The only time that modifying a variable affects a different variable is when the underlying object is mutated.
There is no point in making a distinction between objects and primitives, because it works the same exact way as if you didn't have a function and just used the equal sign to assign to a new variable.
Function arguments are passed either by-value or by-sharing, but never ever by reference in JavaScript!
Call-by-Value
Primitive types are passed by-value:
var num = 123, str = "foo";
function f(num, str) {
num += 1;
str += "bar";
console.log("inside of f:", num, str);
}
f(num, str);
console.log("outside of f:", num, str);
Reassignments inside a function scope are not visible in the surrounding scope.
This also applies to Strings, which are a composite data type and yet immutable:
var str = "foo";
function f(str) {
str[0] = "b"; // doesn't work, because strings are immutable
console.log("inside of f:", str);
}
f(str);
console.log("outside of f:", str);
Call-by-Sharing
Objects, that is to say all types that are not primitives, are passed by-sharing. A variable that holds a reference to an object actually holds merely a copy of this reference. If JavaScript would pursue a call-by-reference evaluation strategy, the variable would hold the original reference. This is the crucial difference between by-sharing and by-reference.
What are the practical consequences of this distinction?
var o = {x: "foo"}, p = {y: 123};
function f(o, p) {
o.x = "bar"; // Mutation
p = {x: 456}; // Reassignment
console.log("o inside of f:", o);
console.log("p inside of f:", p);
}
f(o, p);
console.log("o outside of f:", o);
console.log("p outside of f:", p);
Mutating means to modify certain properties of an existing Object. The reference copy that a variable is bound to and that refers to this object remains the same. Mutations are thus visible in the caller's scope.
Reassigning means to replace the reference copy bound to a variable. Since it is only a copy, other variables holding a copy of the same reference remain unaffected. Reassignments are thus not visible in the caller's scope like they would be with a call-by-reference evaluation strategy.
Further information on evaluation strategies in ECMAScript.
As with C, ultimately, everything is passed by value. Unlike C, you can't actually back up and pass the location of a variable, because it doesn't have pointers, just references.
And the references it has are all to objects, not variables. There are several ways of achieving the same result, but they have to be done by hand, not just adding a keyword at either the call or declaration site.
JavaScript is pass by value.
For primitives, primitive's value is passed. For Objects, Object's reference "value" is passed.
Example with Object:
var f1 = function(inputObject){
inputObject.a = 2;
}
var f2 = function(){
var inputObject = {"a": 1};
f1(inputObject);
console.log(inputObject.a);
}
Calling f2 results in printing out "a" value as 2 instead of 1, as the reference is passed and the "a" value in reference is updated.
Example with primitive:
var f1 = function(a){
a = 2;
}
var f2 = function(){
var a = 1;
f1(a);
console.log(a);
}
Calling f2 results in printing out "a" value as 1.
In the interest of creating a simple example that uses const...
const myRef = { foo: 'bar' };
const myVal = true;
function passes(r, v) {
r.foo = 'baz';
v = false;
}
passes(myRef, myVal);
console.log(myRef, myVal); // Object {foo: "baz"} true
In practical terms, Alnitak is correct and makes it easy to understand, but ultimately in JavaScript, everything is passed by value.
What is the "value" of an object? It is the object reference.
When you pass in an object, you get a copy of this value (hence the 'copy of a reference' that Alnitak described). If you change this value, you do not change the original object; you are changing your copy of that reference.
"Global" JavaScript variables are members of the window object. You could access the reference as a member of the window object.
var v = "initialized";
function byref(ref) {
window[ref] = "changed by ref";
}
byref((function(){for(r in window){if(window[r]===v){return(r);}}})());
// It could also be called like... byref('v');
console.log(v); // outputs changed by ref
Note, the above example will not work for variables declared within a function.
Without purisms, I think that the best way to emulate scalar argument by reference in JavaScript is using object, like previous an answer tells.
However, I do a little bit different:
I've made the object assignment inside function call, so one can see the reference parameters near the function call. It increases the source readability.
In function declaration, I put the properties like a comment, for the very same reason: readability.
var r;
funcWithRefScalars(r = {amount:200, message:null} );
console.log(r.amount + " - " + r.message);
function funcWithRefScalars(o) { // o(amount, message)
o.amount *= 1.2;
o.message = "20% increase";
}
In the above example, null indicates clearly an output reference parameter.
The exit:
240 - 20% Increase
On the client-side, console.log should be replaced by alert.
★ ★ ★
Another method that can be even more readable:
var amount, message;
funcWithRefScalars(amount = [200], message = [null] );
console.log(amount[0] + " - " + message[0]);
function funcWithRefScalars(amount, message) { // o(amount, message)
amount[0] *= 1.2;
message[0] = "20% increase";
}
Here you don't even need to create new dummy names, like r above.
I can't see pass-by-reference in the examples where people try to demonstrate such. I only see pass-by-value.
In the case of variables that hold a reference to an object, the reference is the value of those variables, and therefore the reference is passed, which is then pass-by-value.
In a statement like this,
var a = {
b: "foo",
c: "bar"
};
the value of the 'a' is not the Object, but the (so far only) reference to it. In other words, the object is not in the variable a - a reference to it is. I think this is something that seems difficult for programmers who are mainly only familiar with JavaScript. But it is easy for people who know also e.g. Java, C#, and C.
Objects are always pass by reference and primitives by value. Just keep that parameter at the same address for objects.
Here's some code to illustrate what I mean (try it in a JavaScript sandbox such as https://js.do/).
Unfortunately you can't only retain the address of the parameter; you retain all the original member values as well.
a = { key: 'bevmo' };
testRetain(a);
document.write(' after function ');
document.write(a.key);
function testRetain (b)
{
document.write(' arg0 is ');
document.write(arguments[0].key);
b.key = 'passed by reference';
var retain = b; // Retaining the original address of the parameter
// Address of left set to address of right, changes address of parameter
b = {key: 'vons'}; // Right is a new object with a new address
document.write(' arg0 is ');
document.write(arguments[0].key);
// Now retrieve the original address of the parameter for pass by reference
b = retain;
document.write(' arg0 is ');
document.write(arguments[0].key);
}
Result:
arg0 is bevmo arg0 is vons arg0 is passed by reference after function passed by reference
Primitives are passed by value. But in case you only need to read the value of a primitve (and value is not known at the time when function is called) you can pass function which retrieves the value at the moment you need it.
function test(value) {
console.log('retrieve value');
console.log(value());
}
// call the function like this
var value = 1;
test(() => value);

How to make an object "live" in Javascript without tying it to the DOM

I asked in IRC chat yesterday whether it was possible to have an element update with any changes to an object it references, rather than just keep the value it was given upon being declared. For example
Arr1 = [1,2,3]
i1 = Arr1.length-1
last1 = Arr1[i1]
Arr1.push(4)
Checking last1 at the end of this (arbitrary) example shows it has not updated to reflect the newly added value of 4, so objects in JS aren't "live" by default.
I'm a beginner but I'd worked this out from practice already, but was told this was actually the case... I guess my question wasn't understood.
NodeList objects are "live" however, and I'm wondering if there are other types of object in JS that do so, as it would obviously save lines of code spent updating them.
One important distinction here is that i1 does not "reference" anything here. It is simply storing the numeric result of the expression Arr1.length-1 when that line executed. Likewise, last1 may or may not reference the value that was the third element of Arr1 when line 3 executed, but it maintains no reference to Arr1 itself or anything about it.
As in some other programming languages, variables that are assigned to objects are references, so you can do this:
var obj1 = { prop1: "hello", prop2: "goodbye" };
var obj2 = obj1;
obj2.prop1 = "buongiorno";
console.log(obj1.prop1); // result is "buongiorno"
But this doesn't seem to be quite what you're describing.
It sounds like what you're describing is some sort of reactive programming. JavaScript doesn't really work the way you're imagining, but you could accomplish this using closures:
var Arr1 = [1,2,3];
var i1 = function() { return Arr1.length - 1; };
var last1 = function() { return Arr1[i1()]; };
console.log(i1()); // result is 2
console.log(last1()); // result is 3
Arr1.push(4);
console.log(i1()); // result is 3
console.log(last1()); // result is 4
Note that here, the () parentheses at the end are required to call these functions and get their current value.
One even trickier thing you could do is the following:
function capture(fcn) {
return { valueOf: fcn, toString: function() { return fcn().toString(); } };
}
var Arr1 = [1,2,3]
var i1 = capture(function() { return Arr1.length - 1; });
var last1 = capture(function() { return Arr1[i1]; });
console.log(last1 * 5); // result is 15
Arr1.push(4);
console.log(last1 * 5); // result is 20
Note however that this second technique has its limitations. You have to coerce the values into the type that you would expect or call their .valueOf() method in order for them to produce an actual value. If you just used:
console.log(last1);
You would not get any sort of friendly result.
I interpret your question as why are some variables which are copies are updated when you change the original value and others are not.
This is because some types of variables are Reference Types and others are Value Types. Numbers, dates and strings are value types and are copied whenever you assign them to a variable. Objects, Arrays (which are also an Object) are reference types and are not copied, just referenced.
This example is using value types and any change to the first variable will not be copied:
var foo = 1;
var bar = foo; // this is copying the value from the foo variable to bar
foo = 2;
console.log(bar); // 1
compared to the same thing but with a reference to an object:
var foo = {prop:1};
var bar = foo; // this is creating a reference to the foo object
foo.prop = 2;
console.log(bar.prop); // 2

Categories