4

I know that objects in Javascript are copied/passed by reference. But what about functions?

I was trying out this code when I jumped to something confusing. Here is the code snippet:

x = function() { console.log('hey 1'); }

y = x;

x = function() { console.log('hey 2'); }

y; // Prints function() { console.log('hey 1'); }

If functions like objects are copied/passed by reference, why y is not updated to print 'hey 2'?

If this behavior is because 'x' is assigned with a brand new function, is there any way for variable 'y' to the newly assigned function when x changes?

Adarsh Konchady
  • 2,577
  • 5
  • 30
  • 50
  • This behavior is identical to the behavior you'd see if you did `{ x: 1 }` and `{ x: 2 }` instead of `function() { console.log('hey 1'); }` and `function() { console.log('hey 2'); }`. your current phrasing makes it sound like you're observing different patterns for objects versus functions, which cannot be the case. – apsillers Nov 19 '15 at 16:18
  • A constant I've seemed to find in almost all programming languages is that the `=` operator will only modify the variable it refers to (as in, the actual reference "x") and not the underlying data. If a type has a `.modify()` or `.add()` method, that is one way that underlying data can change so as to be visible via multiple variables. – Katana314 Nov 19 '15 at 16:19
  • Sorry - self-caveat: In JavaScript, `=` is used to modify the properties of an object, which can certainly be visible by other references. eg: `var b = a; a.myprop = 3; console.log(b.myprop);` – Katana314 Nov 19 '15 at 16:20
  • *"If functions like objects are copied/passed by reference, why y is not updated to print 'hey 2'?"* You are making false assumptions. Everything is **pass-by-value** in JavaScript. – Felix Kling Nov 19 '15 at 16:24

3 Answers3

5

Everything in JS is pass by value where the value for objects and functions is a reference.

What is happening here is the same thing that would happen with an object (since functions are just first-class objects):

Here's the gist of what's going on:

x = function() { console.log('hey 1'); }

x points to function() that logs 1 (memory is created for this function)

y = x;

y points to function() that logs 1 (same memory location)

x = function() { console.log('hey 2'); }

x now points to a new function() that logs 2 ( a new memory space), nothing affected y though

y;

y still points to the same function() that logs 1


If you want to have changes to x affect y, what you should do is change the thing they are pointing to, not change what they point to.

For example:

var pointingAtMe = { log: function() { console.log('1'); } }
var x = pointingAtMe;
var y = pointingAtMe;

// change the actual thing x and y are both pointing to
x.log = function() { console.log('2'); } // this line also sets `y.log` and `pointingAtMe.log`since they all point to the same thing
// and the change gets applied to both
y.log(); // logs '2'
Community
  • 1
  • 1
nem035
  • 34,790
  • 6
  • 87
  • 99
1

If functions like objects are copied/passed by reference, why y is not updated to print 'hey 2'?

You are making false assumptions. Everything is pass-by-value in JavaScript. It's correct that objects are represented as references, but that is different from pass-by-reference.

Even if you used a plain object instead of a function, you wouldn't see what you expected:

var x = {foo: 42};
var y = x;
x = {foo: 21};
console.log(y.foo); // still 42

Pass-by-value/reference only describes how variables and parameters are resolved, it doesn't have anything to do with the value of the variables.

If this behavior is because 'x' is assigned with a brand new function, is there any way for variable 'y' to the newly assigned function when x changes?

No. Not without explicitly assigning to y.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

x = function() { console.log('hey 2'); } is not changing the object contained in the x variable, but is modifing the content of x variable.

nem035
  • 34,790
  • 6
  • 87
  • 99
RiccardoC
  • 876
  • 5
  • 10