-1

I see many articles and posts about javascript objects and primitives passed by refference vs passed by value. Though I don't see topic covering functions. Are they passed by value or refference. Therefore I made test myself to check it out.

Cosnider this example:

function sayHello() {
 console.log("Hello")
}

function changeSayHello(func) {
 func = function() {
  console.log("Good Bye");
 }
 func();
} 

sayHello(); // >>  Hello 
changeSayHello(sayHello); // >> Good Bye
sayHello(); // >>  Hello 

You can see the result by running the snippet. From this example I conclude that functions in JavaScript are passed by value. What is your comment.

* EDIT * May be this better explains what I ment. And it shows that function is passed by refference?

var Obj  = function() {
 this.a = 5;
}

var change = function(func) {
 func.prototype.b = 8;
}

var first = new Obj();

console.log(first.b); //undefined

change(Obj);

console.log(first.b);// 8

I don't see why this is marked as duplicate. I saw the proposed answer and there is no example about functions being passed as an argument.

Hairi
  • 3,318
  • 2
  • 29
  • 68
  • 1
    your tests to come to such a conclusion make no sense at all – charlietfl May 19 '18 at 17:41
  • 1
    If you overwrite a variable with another value, it doesn't tell you anything about how the original value was passed. – JJJ May 19 '18 at 17:41
  • 1
    Despite the downvotes, I think this is exactly the sort of question someone coming to JavaScript from C would ask. Not a bad question, just a misunderstanding. – Brian McCutchon May 19 '18 at 17:46
  • 1
    When you do `func = function()`, you're simply assigning `func` a new reference. – user184994 May 19 '18 at 17:53
  • Functions are objects (they have an identity, properties, prototype chain). Assignment and argument passing work for them like for any other object. – Bergi May 19 '18 at 17:54

2 Answers2

3

You're misunderstanding how references work in JavaScript. The correct answer is that everything is passed by value in JavaScript. It's just that some values are references. That means that you can never do this:

function changeX(x) {
    x = y
} 

and expect that to change the value of x outside of the function. JavaScript just doesn't do that.

Functions are reference types, which you can read about elsewhere, but that doesn't affect assignment semantics. You might also want to read: Is JavaScript a pass-by-reference or pass-by-value language?.

Brian McCutchon
  • 8,354
  • 3
  • 33
  • 45
  • You were right about the `C` background. In `C` you can change global variables inside a functio using references. `int a = 1; int b = 2; void change(int * pointer, int * newPointer) { *pointer = *newPointer; } change(&a, &b); // a is now equal to 2` – Hairi May 19 '18 at 18:16
  • 1
    @Hairi Right, you can't do that in JavaScript. – Brian McCutchon May 19 '18 at 18:17
  • Because you probably come from C++. You can do this in Javascript by passing Objects. (Note than functions extend Object). So if you do `var f = new func();` you can pass f to a function and edit its fields. – Attersson May 19 '18 at 18:18
  • @Hairi I added an example below, at the end of my answer – Attersson May 19 '18 at 18:26
  • @Attersson Sure I provided bad example. Thanks for explanation. It is a bit more clear now – Hairi May 19 '18 at 18:32
1

In Javascript a function can be called with any number of arguments. These arguments can be of any type: Numbers, Strings, Objects, Arrays, null, undefined... Defining names for the received arguments in the function signature is just a way to access them inside and use them in the function. These names have functional scope and only exist within a function, nowhere outside. You can even pass more arguments than in the signature.

let t = 5;
console.log("t = ",t);
let func = function(a,b){
  console.log(arguments); //array of arguments, to access unnamed ones
  a=17;
  if(typeof b ==="Object")
      b.hi = "Goodbye"; //in the second call below we use a Number
                    //no type guarantee anytime.
}
obj = {hi:"Hello"};
func(t,obj,3);
console.log("t = ",t); //unchanged by func
console.log(obj); // changed by func
func(1,2,3,4,5,6,7,8);

As you see above, primitive arguments are copied. Objects actually have a reference to the same object copied. Since the reference is to the same object, the actual object is the same and then its changes are also visible outside.

Inside a function you can access the argmuents it was called with, with 'arguments', an array of arguments.

function myFunc(){}

'myFunc' is a reference to the function myFunc and can be passed to other functions.

Not to be confused with 'new myFunc()' which extends 'Object' and returns an "instance" of the function, different than the mere reference to it (and which will have a different "this" context of execution).

function myFunc(a){
  this.b=5;
  this.a=a;
}

let f = new myFunc(6);

console.log(f.a,f.b);

function changeFunc(a){
  a.a=1;
  a.b=2;
}

changeFunc(f);

console.log(f.a,f.b);

So a function can indeed change the fields of another function using the above characteristics of Javascript.

Attersson
  • 4,755
  • 1
  • 15
  • 29