Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning to a new value to an object passed into a function in JavaScript

I'm new to JavaScript (though experienced in C++), and today, I wrote something like this:

function foo(bar) {
    bar = "something else";
}
var x = "blah";
foo(x);
alert(x); // Alerts with "blah", but I was expecting it to alert with "something else"

This confused me a lot, as I've been watching some JavaScript videos by Douglas Crockford, and remember him saying something like "JavaScript is always pass by reference".

The way I can explain this situation is that JavaScript passes references to objects, but those references are copied. This would mean in the foo function, I am assigning a new reference to bar, which then goes out of scope, leaving to reference that x has left untouched. Essentially we start with:

x   ---->"blah"

Then when foo is called, bar references the same data:

x   ---->"blah"
bar -----^

So when "something else" is assigned to bar, this happens:

x   ---->"blah"
bar ---->"something else"

Is that an accurate model of what is actually happening in JavaScript, or am I missing something else?

As an extra question, is there any way to say, change the data referenced by this variable? Is this a situation that comes up often, or can it be easily avoided?

Edit:

Douglas Crockford in the video I watched says "objects are always passed by reference they're not passed by value", which is correct, but arguments to functions are passed by value, it's just the reference is passed by value.

like image 611
oggmonster Avatar asked Feb 20 '14 19:02

oggmonster


People also ask

Can you pass an object to a function in JavaScript?

To pass an object to a JavaScript function, we can add a parameter that accepts an object. const someFunc = (arg) => { alert(arg. foo); alert(arg. bar); }; someFunc({ foo: "This", bar: "works!" });

Can you assign values to a function like an object?

As mentioned, functions are objects. You can work with functions as if they were objects. For example, you can assign functions to variables, to array elements, and to other objects.

How do you pass an object as a parameter to a function?

To pass an object as an argument we write the object name as the argument while calling the function the same way we do it for other variables. Syntax: function_name(object_name); Example: In this Example there is a class which has an integer variable 'a' and a function 'add' which takes an object as argument.


2 Answers

Your interpretation is spot on.

First, you have a variable called x which is a reference to a string object. Let's say that memory is 0x100. x points to 0x100, which contains the bytes blah:

var x = "blah"; // x is 0x100 which references a string in memory

Next, you pass 0x100 into the function foo:

function foo(bar) {
    bar = "something else";
}

As everything in JavaScript is passed by value, even references, JavaScript makes a copy of this reference in memory, which is now called bar within that function:

foo(x); // Copies the value of x (a reference) to bar

At this point, we have two separate variables. x and bar. Both happen to have the same value, 0x100. Thus, if you were to change a property of the object either of those is referencing, it would affect both x and bar.

However, what you're doing is assigning bar to point to something else:

bar = "something else"; // Now references some other string we just created

Now, bar gets re-assigned to reference a new string we've just allocated memory for. bar no longer has a value of 0x100, it now has a value of some other address (say 0x500). x of course still has a value of 0x100 since bar was merely a copy of x, and not a reference to x.

For this reason, when you:

alert(x);

You'll still get the original value, as that is what x is pointing to.

Second question:

is there any way to say, change the data referenced by this variable? Is this a situation that comes up often, or can it be easily avoided?

Yes, just wrap it in another object. For example:

var x = {Value: "blah"};
foo(x);

Now, we have a reference to an object with a property called Value, which contains a reference to a string in memory somewhere.

In foo, we can do:

bar.Value = "something else";

Which will affect the Value property of x, since both bar and x referenced the same object, and you never changed the value of either of them.

In other words, you cannot re-assign the reference you're passing into a function, since you're simply re-assigning a copy. You can, however, change a property of an object being referenced, since other copies of that reference all point to the data you're changing.

like image 141
Mike Christensen Avatar answered Oct 30 '22 07:10

Mike Christensen


Your interpretation is correct.

You can change the values of keys in an object, which lets you do something similar to pass-by-reference:

function foo(bar) {
  bar.msg = "something else";
}
var x = { msg: "blah" };
foo(x);
alert(x.msg);
like image 31
jkinkead Avatar answered Oct 30 '22 06:10

jkinkead