Mitya
Mitya

Reputation: 34576

Javascript functions - copied by reference, but what's going on here?

Given functions in JavaScript are a reference type (copied by reference, unlike simple types), what precisely is going on here?

var func = function() { alert(1); };
var func_alias = func;
var func = function() { alert(2); };
func_alias(); //1

If func_alias is a reference to func, why is it non-updating? Wouldn't you expect its invocation (line 4) to return 2?

This is different behaviour from other by-reference examples:

var obj = {prop: 'val'};
var obj_alias = obj;
obj.prop = 'updated val';
alert(obj_alias.prop); //updated val - not original one

func_alias seems to have kept a copy of the original, pre-overwrite func - in short, it seems to behave as though it's copied it by value. This of course is disproven by:

var func = function(){}
var func_alias = func;
func === func_alias; //true

Upvotes: 0

Views: 160

Answers (3)

techfoobar
techfoobar

Reputation: 66693

var func = function() { alert(1); };

Here a new function is created and a reference to it is copied to func

var func_alias = func;

The function reference stored is func is assigned to another variable func_alias

var func = function() { alert(2); };

Another new function is created and a reference to it is assigned to func. The reference to the first function stored in func is lost. But since you saved it in func_alias before overwriting func, it can still be called.

func_alias();

func_alias was assigned a reference to the first function in step 2 (and wasn't overwritten after that point). So the first function is called.


EDIT #1

As per your second example using an object:

var obj = {prop: 'val'};

Here, a new object is created and a reference to it is assigned to obj

var obj_alias = obj;

The reference is copied to another variable obj_alias

obj.prop = 'updated val';

Here you are not overwriting the value of obj, but only overwriting a property of the object pointed to by that reference stored in obj. The value of obj (i.e. reference to the object created in first step) remains intact.

In your function example, you were actually overwriting the variable func with a new function reference.

alert(obj_alias.prop);

The value of obj_alias as well as that of obj is still the same, since you haven't overwritten either. They both hold a reference to the object created in step 1.


EDIT #2

This can maybe be explained well in C terms.

  • When you create an object via var obj = {prop: 'val'}; - lets say the object is stored at address 0x0001 in memory. i.e. the actual value of obj is 0x0001

  • When you assign it to obj_alias, obj_alias also gets the value 0x0001 - now both variables point to something stored at address 0x0001

  • When you do obj.x = y, you aren't overwriting the value of obj, but only using obj to access the object stored at 0x0001 and modifying one of its properties.

Upvotes: 2

Germann Arlington
Germann Arlington

Reputation: 3353

If you consider your program code to be a large warehouse that allows you to store and use objects.
Then your code does the following:
Line 1 - let's store the function SOMEWHERE and I (first variable) will remember where it is [you don't (and can't) specify particular location here].
Line 2 - let someone else remember where the function is stored too.
Line 3 - let's store ANOTHER function SOMEWHERE and I (first variable) will remember where it is [you don't (and can't) specify particular location here].
Line 4 - ask the guy from Line 2 where my function is.

What is you expected result?

Upvotes: 0

xdazz
xdazz

Reputation: 160883

The difference is

in the first piece of code, you let a variable refer to another object.

in the second piece of code, you changed the property of the object, the two variable is refer to the same object.

var func = function() { alert(1); };
var func_alias = func; // func_alias refer to the first function.
var func = function() { alert(2); }; // let func refer to another function, but won't affect func_alias
func_alias(); //1

Upvotes: 1

Related Questions