Pass by reference or pass by value - javascript

Does object in javascript pass by reference?
If yes why this code not working.
function change(myObj)
{
myObj={};
myObj.a=2;
}
o={a:1};
change(o);
alert(o.a); //alert 1
but when I do
function change(myObj)
{
myObj.a=2;
}
o={a:1};
change(o);
alert(o.a); //alert 2

I'll explain this thoroughly
o={a:1};
first you set global variable o to be a reference of new anonymous object that have attribute variable a with value = 1 name this object {a:1} as '1A'
change(o);
now you call function change and javascript check of typeof variable o and it's 'object' actually it's should be 'reference that pointed to object' so the reference of object {a:1} is pass into function change by the way if variable is primitive it will pass only by value
function change(myObj){
now function change create variable myObj with typeof 'undefined' by default and then change to 'object' because it got reference parameter and now the variable myObj is a reference variable that pointed to object '1A' => {a:1} and myObj is visible only in function change
and global variable o maybe still point to object '1A' => {a:1} if myObj is just a copy of reference to object '1A' => {a:1} by language design
myObj={};
now the reference variable myObj is point to new anonymous empty object {} name this object as '2B'
myObj.a=2;
}
now you use reference myObj to set object '2B' => {} to have new attribute a with value = 2
and end the scope of function that mean global can't see object '2B' => {a:2}
alert(o.a); //alert 1
variable still point or may be point back to object {a:1} ,reference o can't lose it point, because object '2B' => {a:2} can't be seen outside function change and will be destroyed by garbage collection because it's lost the reference and object '1A' => {a:1} can't be destroyed by garbage collection because variable o still point at it that why you call o you receive object '1A' => {a:1}
sorry for my bad grammar but I try my best to make it easy to read.

The reference to the object is passed to methods. In your first example you are modifying the reference to point to a different object instead of trying to change the object pointed to by the reference and so, the changes are not visible outside that method.
In your second example, you are changing the state of the object pointed to by myobj reference and hence are visible outside the method.

In this case you are overwriting the reference to actual object.
function change(myObj)
{
myObj={}; //overwriting the reference in myObj here.
myObj.a=2;
}
o={a:1};
change(o);
alert(o.a); //alert 1
Think of it this way:
function change(myObj = referenceToObjectPassedIn)
myObj = new Object() ;
// referenceToObjectPassedIn lost in limbo
myObject.a = 2; //modifying newly created object.
To solve your problem you will have to return the new object.

In example 1 you change what myObj references, so you end up changing a different object then the one you intended. When
alert(o.a);
is executed, o.a hasn't been changed since the object declaration, so 1 is returned. I hope that helps a bit. Also read this and it should clear some things up, helped me out when I was first learning JavaScript: http://www.snook.ca/archives/javascript/javascript_pass/.

Related

JavaScript: Is everything in a closure accessed by reference?

So far this is my thought process:
In JS primitives are pass by value, and objects are pass by reference.
let var1 = 10 // var1 is assigned a reference to the primitive 10
let var2 = var1 // var1 is evaluated to the primitive 10, var2 is assigned a reference to the primitive 10
// var1 and var2 are independent. This is pass by value
const obj1 = {} // obj1 is given a reference to the object created in memory by the object literal
const obj2 = obj1 // obj2 is given a reference to the exact same object obj1 is pointing to
// obj1 and ob2 are pointing to the same object, they are not independent variables. This is pass by reference
What I am confused about is closures. In closures, it seems that everything is passed by reference. Even variables that are referencing primitives.
function func() {
let a = 0;
return [
function () {
a++;
return a;
},
function () {
a++;
return a;
},
];
}
const [a, b] = func();
console.log(a(), b()); //will result in logging 1, 2
In this example the func defines a local variable a to 0, then includes it in the closure of 2 anonymous functions that are being returned. Then by mutating a from either function, its clear that they are referencing the same spot in memory.
Previously I had thought both functions just created an unaccessable object to store its closure in and copied over the variables. If this was the case then the variables would be copied by value, and each anonymous function would have a variable named a in their closure that referenced the primitive 0. Then you could safely mutate a in each function.
But now it's clear that instead, the functions have a reference to the actual variable a that was defined when func was executed.
Is my understanding of how closures work correct? And is there any other way to reference a variable itself, instead of the primitive that it points to?
But now it's clear that instead, the functions have a reference to the
actual variable a that was defined when func was executed.
That is a correct thought. A JS function keeps a 'reference' to an outer scope (a scope where a function is created) in its closure and access to that scope have all functions which were created in it.
Below example is similar to yours. Access to a global variable is possible due to closures:
let gl = 100;
function f(){
gl++;
return gl
}
function g(){
gl++;
return gl
}
f();
g();
gl;
In JS primitives are pass by value, and objects are pass by reference.
The concept "pass by reference" is not applicable in JavaScript. Pass by reference would mean that you could design a function func such that the following could happen:
let a = {};
let b = a;
func(a);
if (a !== b) console.log("This will not happen. This is not C++");
This is only possible in languages that support "pass by reference". Not so in JavaScript.
In JavaScript, objects are references, and they get passed by value just as any other value is passed by value. It can be confusing that in JavaScript-land the term "object" is used both for the reference and for the referenced "struct".
obj1 and ob2 are pointing to the same object, they are not independent variables. This is pass by reference
No, this is not the concept of "pass by reference". Even though obj1 and obj2 are pointing to the same object there are independent variables. Whether or not these two variables are object types or not, you can assign a different value to one of those variables and that will not affect the other.
Objects have the distinguished feature that they can be mutated, but that is another concept. Primitives cannot be mutated -- they are immutable. This has nothing to do with the concept of "pass by reference" which is not applicable to JavaScript.
In closures, it seems that everything is passed by reference. Even variables that are referencing primitives.
In your example the variable a is not referencing a primitive, its value is a primitive. In your example, there is only one variable a, and it can be accessed by the function func, and by the two anonymous functions. There is no "pass by <something>" happening anywhere here.
In this example the func defines a local variable a to 0, then includes it in the closure of 2 anonymous functions that are being returned.
I wouldn't use the term "includes" here. It is just that functions have access to the outer scope they are defined in, and in this case that means the two anonymous functions have access to the scope of func, which includes the variable a.
But now it's clear that instead, the functions have a reference to the actual variable a that was defined when func was executed.
Their access to a is the same as the access that the code in func has to that variable. There is no difference.
And is there any other way to reference a variable itself, instead of the primitive that it points to?
Referencing a variable and not its value is exactly what object properties offer. Object properties are names that identify the property.
For example:
const myVars = { "a": 1, "b": 2 };
Now I have a reference to that property, and I could even keep that in a variable:
let prop = "a";
Now I have a variable for the name and can use it to retrieve the value:
console.log(prop); // a
console.log(myVars[prop]); // 1
I can change prop to refer to the other property:
prop = "b";
console.log(prop); // b
console.log(myVars[prop]); // 2
So you could say that with prop I have a reference to a primitive value.

reading / assigning reference types in JavaScript

I like to think I have and understanding of reference types, but I am wondering what I am missing here, what is happening under the hood.
let o = {
foo: 'bar'
};
console.log(o) // logs the object.
let p = o; // assigns reference to object
I have seen this a thousand times and move on without a thought, but this time it gave me an unexpected psychedelic jolt.
In both cases my mind reads this as 'read the value of o and'. However, one will log the actual data stored whereas the other will return a reference. What step am I missing that makes these two lines differ?
is let p = o; how things normally work, but
console.log(o) is causing some type of implicit / default call.
Or is it the inverse, that o will naturally pull the actual object
from the heap but an assignment will by nature always assign the
reference?
"when x JavaScript will z"
Can someone explain the workings of this so I understand the exact why of it?
If you copy the value, then you copy a reference to the object.
If you do anything else with it, then the reference is followed and the object worked with.
The value of o is a reference to an object.
If you assign o to p then you copy that reference and p is also a reference to the object.
If you access o.foo then you follow the reference to the object and do something with the foo property of it.
If you pass o to a function, then you copy the reference to the parameter in the function. If that function then accesses paramater.foo then it follows the reference to the object and does something with the value of foo on it.
In your code example, both o and p are pointers to the same underlying Javascript object.
When you do this:
let o = {
foo: 'bar'
};
o contains a pointer to a Javascript object. It's important to not think of o as containing the object itself. It contains a pointer to the object and the object exists independent of either variable itself. I'm purposely not calling it a "reference" to the object because it doesn't behave fully like a reference. If I assign something else to p, that doesn't change o in any way (thus it's not a full reference). It behaves like a pointer would in a language like C.
When you assign such a pointer as in:
let p = o;
Javascript makes a copy of the pointer from o and puts it into the p variable. Each variable o and p now contains a pointer to the same object. If you modify the object via either the o or p pointer, there's only one object that each points to so you will see the modification no matter which variable you use to look at the underlying object.
// create an object and assign a pointer to that object to the variable o
let o = {
foo: 'bar'
};
// assign a pointer to the same object to the variable p
let p = o;
// modify the object pointed to by o
o.foo = 'hello';
// since both variables point to the same object, both see the modification
console.log(o.foo); // 'hello'
console.log(p.foo); // 'hello'
Both o and p point to the same underlying object. Thus modifying that object, no matter which pointer you use to modify it will modify the underlying object and both pointers will still be pointing to the same (now modified) object.
p is not a reference of o because if I assign something else to p, it does not affect o at all.
let o = {
foo: 'bar'
};
let p = o;
o.foo = 'hello';
p = {foo: 'goodbye'}; // assign different object to p
console.log(o.foo); // o not affected by assignment of different pointer to p
When you pass that pointer to a function as in:
console.log(o);
It again makes a copy of that pointer (not a copy of the object) and passes it as an argument to the function. It is then up to the function you call to decide what to do with the argument you passed it. In this case, console.log() looks at the type of the argument, finds it is a pointer to an object and then decides to use the code it has for outputting the contents of an object. It is the inner workings of console.log() that analyzes the type of the argument and decides what to do with it.
Passing an object to a function in Javascript is just like assigning that object to another variable and in fact, that's what Javascript is doing. It is creating a new temporary variable scoped to that function and assigning a copy of the pointer to that object and then making that named parameter variable available inside the scope of the function. The function can then access that object through its local pointer to it.

Passing an hash through parameter

I'm a little confused about the passing of a hash as parameter to a function.
I know that when a variable is passed to the function through a parameter, to this is applied a copy of the value.
But this is not valid with the hashes, at least not always.
Example:
var a = {b: 'hello world'};
var change = function(h){
h = true;
};
var change_v2 = function(h){
h.b = 'another hello';
};
console.log(a); // will print the original hash
change(a);
console.log(a); // naturally, will print the original hash
change_v2(a);
console.log(a); // this print b == 'another hello'
So, why the reference is used sometime for the hashes?
Can someone explain how javascript works in this case?
The simple answer to your question is that a value was copied -- a does not contain any object (what you called a hash) but actually contains a reference to the object and this reference was copied into the parameter local.
Read below for a more detailed explanation of why this happens, pass-by-value vs pass-by-reference.
In JavaScript, variables do not hold objects, they hold a reference to an object. This is an important distinction.
All parameters are pass-by-value in JavaScript. The object references stored in variables are passed by value.
These two behaviors combine to cause the specific behavior you are seeing. Let's lay out some examples of each passing behavior to prove that JavaScript passes arguments by value.
function foo(a) {
a.bar = 2;
}
var b = { bar: 1 };
foo(b);
b.bar would still be 1 if objects were passed by value, but this is not the case in JavaScript.
b.bar would be 2 if (a) the object reference was passed by value, or (b) the argument itself was passed by value.
So in this case, "pass reference by value" and "pass argument by reference" don't have a difference in behavior. Now let's introduce a case where they are different.
function foo(a) {
a = { bar: 2 };
}
var b = { bar: 1 };
foo(b);
b.bar will be 1 if the object is passed by value, which isn't what happens.
b.bar will also be 1 if the object reference is passed by value, which is what happens.
b.bar will be 2 if the argument is passed by reference.
So in summary, you have to realize two things:
Variables never contain objects, but they can contain a reference to an object. Two variables both holding a reference to the same object will reflect changes made to that object.
All arguments are passed by value, that is, the callee has no access directly to the variable that was passed in, but only to the value received by the parameter -- which can be an object reference. Manipulation of that object can cause the appearance of pass-by-reference, but note that the variable passed into the function still refers to the same object so the passed variable was not modified in any way.
As a side note, if objects were values that could be directly stored in variables, then {} === {} would be true, but it's not -- because the references are compared and found to be not equal, as these references refer to two different objects.
Javascript is pass-by-reference. Always. Assignment changes a name to refer to some value.
So,
function foo(h)
{ h = "bar"; }
The name h is a parameter to the function. The assignment affects the name h only, and that name exists only in the scope of the call to the function.
In contrast, the statement h.b = "bar"; does not assign to the name h. It assigns to the field b within the object that is referenced by the name h.
This is because JavaScript passes parameters by value.
Passing a parameter by value is like assigning formal parameters values to actual parameters. For example consider
function f(obj) { obj.a = 10; }
o = { a : 20 };
f(o);
The above code will function as if the value of o is assigned to obj like if you do
o = { a : 20 }
obj = o;
obj.a = 10;
console.log(o.a);
you will see the same effect.
See a detailed explanation here

Basic JS - Why does this obj not change to undefined?

In the below code, I understand why person.name is changed to "john", but I do not understand fully why person does not reference undefined in memory, per the obj = undefined on the next line.
var person = { name: "wtf" };
function doStuff(obj) {
obj.name = "john";
obj = undefined;
}
doStuff(person);
person.name now equals john and person still references or "points" to the object instead of "pointing" to nothing in memory, i.e. undefined. I could carry forward in my learning and simply rely on this to work this way, but I'd never be able to articulate exactly why it works this way.
The obj parameter in your function is passed a reference to person in the function call
doStuff(person);
The parameter value is a copy of the object reference stored in person. When you give the obj variable a new value, therefore, that has no effect on person.

Is there thing like pass by value pass by reference in JavaScript?

When i started learning function in C++ its all around pass by value and reference.
Is there something similar we have in javascript ?
If yes/not how it works in case of javascript?
Thanks all.
Other answers to this question are correct - all variables are passed by value in JavaScript, and sometimes that value points to an object.
When a programming language supports passing by reference, it's possible to change where the variable points from inside a function. This is never possible in JavaScript.
For example, consider this code which attempts to reassign the passed variable to a new value:
function changeCaller( x ) {
x = "bar"; // Ha ha!
}
function testChangeCaller() {
var x = "foo";
changeCaller(x);
alert(x); // still "foo"
}
testChangeCaller();
Attempts to point variables at new objects fails in the same way the above example fails to reassign a primitive string:
function changeCaller( x ) {
x = new Object(); // no longer pointing to the same object
x.a = "bar";
}
function testChangeCaller() {
var x = new Object();
x.a = "foo";
changeCaller(x);
alert(x.a); // still "foo"
}
testChangeCaller();
The feature which leads people to believe they're dealing with a pass-by-reference scenario is when modifying objects. You can make changes to an object or array, because the local variable points to the same object:
function changeCaller( x ) {
x.a = "bar";
}
function testChangeCaller() {
var x = new Object();
x.a = "foo";
changeCaller(x);
alert(x.a); // now "bar", since changeCaller worked on the same object
}
testChangeCaller();
Hope this helps!
JavaScript is always pass by value, never pass by reference. A lot of people confuse this because of the way objects work.
There is no "pass by reference" for any variable in JavaScript (no, not even if an object is assigned to that variable). All variables and arguments are assigned by value. If the assigned value is an object, then the value of the new variable is a reference to that object, but assigning a new value/object to the new variable will not affect the original variable.
Some people term this behaviour passing "value by reference".
A comparison - PHP
$foo = "foo";
$bar = &$foo; // assign by reference
$bar = "bar";
echo $foo; // -> output: "bar"
JavaScript
foo = {"foo": true};
bar = foo; // assign value by reference
bar = {"bar": true};
alert(JSON.stringify(foo)); // -> output: '{"foo": true}
Regard the discussion, the considerations about "value" and "reference" are wrong on the exception of the Pointy comment.
Javascript like other reference laguages like c# or java, don't pass a referece to the variable itself to the method, but the reference of the object referenced by the variable.
What the people here is expecting, is passing a pointer to the variable which is referencing the object, pass by pointer is not the same as pass by reference, and sure is not the same as pass by value.
The behavior expected here is pass by pointer.
Pass by reference sends the reference to the object.
Pass by value copy the object stored in the variable and pass the copy
to the method.
The pass by value, pass by reference discussion is an evil meme. This evil meme crops up in Java discussions too.
It's simple: The bit pattern of the value is copied to the parameter. It doesn't matter if the bit pattern is an int or if it's the address of an object -- it's just copied, bit by bit, into the parameter. It couldn't be simpler. The run-time isn't doing something special for primitives versus references. It simply, and always, just makes a copy of the value.
The computer science term for this is "pass by value."
Pass by reference just isn't used in programming any more. In older languages, like Pascal, you could code a function to directly alter the value in the calling routine. So, for example, an int variable in the calling routine could be altered in the called function.
Primitive values are passed via value and objects are passed via reference.
Strings are immutable, so they are passed via reference although they are considered as primitive type.

Categories

Resources