10

I'm trying to pass primitive variables by reference.

var foo = 2;
function inc (arg) {
    arg++
}
inc(foo) //won't increment foo

The above doesn't work because in JavaScript, primitives (like numbers) are passed by value, while objects are passed by reference. In order to pass primitives by reference, we need to declare them as objects:

var foo = new Number(2)
function inc (arg) {
    arg++
}
inc(foo) //increments foo

This seems like a pretty hacky workaround, and probably hurts execution speed. In other OO languages, we can pass "pointers" or "references" to functions. Is there anything like this in JS? Thanks!

5
  • What are you asking? There is no pass-by-reference in JavaScript for primitives. Commented Sep 19, 2016 at 22:00
  • The real problem is the scope You should read about how JS works. An easy link: w3schools.com/js/js_scope.asp Commented Sep 19, 2016 at 22:09
  • Better link: developer.mozilla.org/en-US/docs/Web/JavaScript/Closures Commented Sep 19, 2016 at 22:10
  • In other OO languages, we can pass "pointers" or "references" to functions not nearly all of them. Java, for example, doesn't even have functions (not real ones, anyway - Java 8 has syntactic sugar over classes). Question is, why would you want to be able to pass by reference? What benefit does that have? Commented Sep 19, 2016 at 22:18
  • Can a c++ addon module do this? Commented Apr 5, 2024 at 14:20

1 Answer 1

14

You can't pass primitives by reference in Javascript - and the example "workaround" does not work. Here's why:

var foo = new Number(2)  // line 1
function inc (arg) {     // line 2
    arg++                // line 3
}

Line 1 sets foo to a Number object wrapper with primitive value 2.

Line 2 defines a formal parameter arg which has its own storage location in function scope to hold a copy of the value of the argument.

Line 3 increments the actual parameter value (a copy of the Number object reference) where it is stored - in memmory allocated for arg, not foo. If you check the primitive value of foo after the call it is still 2.

In practice you can pass a reference to an object with a foo property that is incremented:

var obj = {}
obj.foo = 2
function incFoo (obj) {
    obj.foo++
}
incFoo()  // obj.foo now 3

Essentially there are no address pointers available in ECMA script to reference primitive values.

Sign up to request clarification or add additional context in comments.

4 Comments

Objects are almost a pass-by-reference. It's more of pass-by-copy-of-a-reference. But it's a rather minor detail - it only means that if you accept a parameter obj in your function obj = null does not wipe out the actual object. Other than that - you're correct, especially about new Number not being a workaround.
`@vlaz Totally agreed but perhaps think of it in different terms. I long ago discounted "all parameters are passed by value (a copy operation) except for objects which are passed by reference" in favor of "all parameters are passed by value, including object data types, because object data types contain a reference to object data stored elsewhere." ;-)
Can a c++ addon module do this?
No, because C++ modules cannot alter the behaviour of JavaScript. Only define values and call functions

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.