10

I'm trying to create an array that maps strings to variables. It seems that the array stores the current value of the variable instead of storing a reference to the variable.

var name = "foo";
var array = [];

array["reference"] = name;

name = "bar";

// Still returns "foo" when I'd like it to return "bar."
array["reference"];

Is there a way to make the array refer to the variable?

Steve Geluso
  • 139
  • 1
  • 2
  • 7

5 Answers5

15

Put an object into the array instead:

var name = {};
name.title = "foo";

var array = [];

array["reference"] = name;

name.title = "bar";

// now returns "bar"
array["reference"].title;
Lars Blumberg
  • 19,326
  • 11
  • 90
  • 127
9

You can't.

JavaScript always pass by value. And everything is an object; var stores the pointer, hence it's pass by pointer's value.

If your name = "bar" is supposed to be inside a function, you'll need to pass in the whole array instead. The function will then need to change it using array["reference"] = "bar".

Btw, [] is an array literal. {} is an object literal. That array["reference"] works because an Array is also an object, but array is meant to be accessed by 0-based index. You probably want to use {} instead.

And foo["bar"] is equivalent to foo.bar. The longer syntax is more useful if the key can be dynamic, e.g., foo[bar], not at all the same with foo.bar (or if you want to use a minimizer like Google's Closure Compiler).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
RichN
  • 6,181
  • 3
  • 30
  • 38
  • This is the answer I was looking for. I realize objects can be used for a similar effect, but this answer gets at the heart of the issue. – Steve Geluso May 05 '11 at 01:31
  • 20
    Javascript doesn't always pass by value...for example. if you have `abc = {a:2};` and then `ddd=abc;`. You don't have two objects. ddd keeps a reference to abc. And if you change something on ddd it will change on abc. Which is not pass by value means. – Muhammad Umer Aug 30 '13 at 22:13
  • 3
    This should not be the accepted answer. You can store a reference to an object in javaScript like Muhammad Umer said. – User2 May 23 '14 at 13:38
  • Objects are *always stored as reference in javascript*. Please edit this this – ICW Aug 15 '19 at 20:46
  • @YungGun Can you clarify/elaborate? I don't know what you mean by "this this" because the answer didn't use `this`, unless you mean just one "this" referring to the whole answer? Also I can't tell if you're quoting or telling a fact; if it's the former I couldn't find that line, if it's the latter then, well, I'm still not clear what you're trying to say but it doesn't seem relevant to the asked issue which is about reading and writing to a variable indirectly (through a difference name), something that is just not possible in Javascript and most languages. – RichN Aug 16 '19 at 07:29
  • Sorry, didn't mean to say "this this", that was a typo. I mean that this answer is incorrect. You are *always* reading and writing to a variable indirectly in javascript, because, as you even said yourself, var stores the pointer. If we have an array `var a = [{n: "one"}, {n: "two"}, {n: "three"}]` then we have an array with 3 pointers to objects. If you do `var o = a[0]` then `a[0]` and `o` refer to the same object. If you change `o.n = "indirect_write"`, then the array a is now `[{n: "indirect_write"}, {n: "two"}, {n: "three"}]` @RichN – ICW Aug 16 '19 at 17:06
  • @YungGun Semantics aside, using your example, what OP want to do is to be able to do `o = { n: "indirect_write" }` and not `o.n = "indirect_write"` like in your example and still get the same final result. Or vice versa doing`a[0] = { n: "indirect_write" }` and having that new value reflected in `o`. In some languages such as C++ and C# you can. When one says that "language X does not have pass by reference", this is what they mean. I suspect that those who argue otherwise just have never encountered such feature hence the confusion. – RichN Aug 17 '19 at 07:04
  • @YungGun note that as a comparison, in C you can sort of do this albeit slightly less transparently and even then they have no qualms about saying that C does not have pass by reference. See https://stackoverflow.com/questions/2229498/passing-by-reference-in-c – RichN Aug 17 '19 at 07:29
  • 1
    @RichN I wasn't referring to OP's case, my example had nothing to do with OP - It was to demonstrate that two variables may refer to the same object within JS which is only possible when passing by reference. That linked stack overflow post is also just plain wrong: They're the ones playing a silly semantics game. Passing by reference means passing a pointer. Saying that it passes the Value of a pointer is just an incoherent word game. Reference = Pass by pointer. If you don't believe that then pass by reference has no meaning whatsoever in programming. C and C++ were my first languages... – ICW Aug 21 '19 at 17:58
  • 1
    It really boggles my mind anyone would legitimately argue that C doesn't have pass by reference - Its incoherent. PassByReference was a term invented to describe passing a variables memory location as a variable rather than the data value itself. In C you designate a variable as either being a pointer or not with a \*, when you pass a pointer instead of a regular data variable that is pass-by-reference, a pointer is a *reference* to the object of interest. Thats the only useful meaning of the term pass-by-reference. It is technically just a "Value" still, but so is every var in programmin ever – ICW Aug 21 '19 at 18:00
  • @YungGun If it has nothing to do with OP's case then it's not relevant. OP was asking for a feature which doesn't exist in Javascript but exists in C++ and C# although now that I think of it, it's usually the other way around, storing a reference to an array element in a variable. A feature is of practical important, you're the one debating the semantics which makes it theoretical. I'm genuinely grateful that you replied unlike the previous guy. And since we've established it's not relevant I'm not continuing this here anymore. Please suggest a different channel if you still want to continue. – RichN Aug 22 '19 at 08:09
5

Try pushing an object to the array instead and altering values within it.

var ar = [];

var obj = {value: 10};
ar[ar.length] = obj;

obj.value = 12;

alert(ar[0].value);
Marty
  • 39,033
  • 19
  • 93
  • 162
2

My solution to saving a reference is to pass a function instead:

If the variable you want to reference is called myTarget, then use:

myRef = function (newVal) {
    if (newVal != undefined) myTarget = newVal;
    return myTarget;
}

To read the value, use myRef();. To set the value, use myRef(<the value you want to set>);.

Helpfully, you can also assign this to an array element as well:

var myArray = [myRef];

Then use myArray[0]() to read and myArray[0](<new value>) to write.

Disclaimer: I've only tested this with a numerical target as that is my use case.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yatt
  • 21
  • 1
0

My solution to saving a reference is to pass a function instead:

If the variable you want to reference is called 'myTarget', then use:

myRef = function (newVal) {
            if (newVal != undefined)
                myTarget = newVal;
            return myTarget;
        }

To read the value, use myRef();. To set the value, use myRef(value_to_set);.

Helpfully, you can also assign this to an array element as well:

var myArray = [myRef];

Then use myArray0 to read and myArray[0](value_to_set) to write.

Disclaimer: I've only tested this with a numerical target as that is my use case.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yatt
  • 1