0

I understand that javascript is always "Pass-by-value". Even when when assigning an object, it passes a value which is a reference to the object.

1: var obj1 = {name: "bob"};
2: var obj2 = obj1;
3: obj2.name = "joe";
4: console.log(obj1.name);    // output: "joe"
5: obj2 = {name: "ron"};
6: console.log(obj1.name);    // output: "joe"

On line 4, both obj1 and obj2 contain a reference to the same object, and that we are able to manipulate that object through both variables. But line 5 sets obj2 to refer to a new object. now obj1 and obj2 have references to 2 different objects. This all makes sense so far.

My question is this: is there any way to access the object itself and not just references to it? So that instead of simply manipulating the object we can change it to a whole new object and any variables that referenced it would now reference the new object? something like this:

var obj1 = {name: "bob"};
var obj2 = obj1;
var actualObject = GetActualObjectReferencedBy(obj2);
actualObject = new Date();
console.log(obj1)      // output: the current date;
console.log(obj2)      // output: the current date;

So that actualObject is just that. the actual object that everything is referring to, not just a reference. And making ANY changes to it doesn't break the references.

Here is an example of why I want to do this:

function Person(n){
  this.name = n;
}
function attachProxies(){
  for(var i = 0; i < arguments.length; i++){
    var actualObject = GetActualObject(arguments[i]);
    actualObject = new Proxy(actualObject, {
      get: function(obj, prop){ return "I'm " + obj[prop]; };
    });
  }
}

var guy1 = new Person("bob");
var guy2 = new Person("joe");
var guy3 = new Person("rom");
attachProxies(guy1, guy2, guy3);

console.log(guy2.name);    // output: "I'm joe"

The closest thing I can figure is this:

function attachProxies(obj){
  return new Proxy(obj, {
    get: function(obj, prop){return "I'm "+obj[prop];};
  });
}
var guy1 = new Person("bob");
var guy2 = new Person("joe");
var guy3 = new Person("rom");
guy1 = attachProxies(guy1);
guy2 = attachProxies(guy2);
guy3 = attachProxies(guy3);

But that's much more limited and repetitive.

I've tried looking around but I can't seem to find any way of doing this. If it's not possible, please help me understand the reasoning.

Edit:

I don't believe this counts as a duplicate because I acknowledge in the setup to my question that javascript passes by value. The supposed duplicate only states that but does not answer my question of whether there is any way access the object.

tyler mackenzie
  • 622
  • 7
  • 18
  • 2
    https://stackoverflow.com/a/16880456/560648 – Lightness Races in Orbit Mar 03 '19 at 19:39
  • 2
    There's no way of doing what you describe in JavaScript. – Pointy Mar 03 '19 at 19:44
  • 1
    Possible duplicate of [javascript pass object as reference](https://stackoverflow.com/questions/16880418/javascript-pass-object-as-reference) – Patrick Hollweck Mar 03 '19 at 19:44
  • Yes that particular answer describes what I already know and stated in the setup to my question. But not my actual question. – tyler mackenzie Mar 03 '19 at 19:49
  • @Pointy I believe you, but do you know if there is any particular reasoning behind this? is there a flaw in the way I'm thinking about the problem? is there an article you can point me to that will help me understand it? – tyler mackenzie Mar 03 '19 at 19:58
  • That's just not how JavaScript works. **All** "object" values are actually "reference to object" values. There's probably more JavaScript code than code in any other language, so people generally seem to be able to live with the behavior. – Pointy Mar 03 '19 at 20:22

1 Answers1

1

No, this is not possible. You cannot get access to the memory where the object's contents are stored and replace them with different contents taken from another object.

Well, you can do that, but in a limited way. You can change the object's contents, which are mainly the object's properties, by simply assigning them new values. You can even swap out its prototype chain with Object.setPrototypeOf. (Assuming that the object isn't frozen or otherwise non-configurable).

But what you absolutely cannot do is swap out the object for an object of a different internal type, such as your plain object-literal object for a Date instance of even a Proxy. This is fundamentally impossible.

Your "the closest thing" solution is indeed the closest thing you can do, and it involves assigning new reference values to all the places (in your case, variables) that stored the old reference. You can however make it less repetitive if your wrapper function supports the syntax

[guy1, guy2, guy3] = attachProxies(guy1, guy2, guy3);
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • So basically I just need to re-structure the way I think about it. and either write it like your example. or even do something like `var guys = [guy1, guy2, guy3]; attachProxies(guys)` – tyler mackenzie Mar 03 '19 at 23:29
  • @tylermackenzie With that syntax, you might change the elements of the `guys` array, but never have the `guy1`, `guy2` and `guy3` variables refer to the new proxy. – Bergi Mar 04 '19 at 11:43
  • Ah right, yes. I guess I'd have to always use them through the array. – tyler mackenzie Mar 04 '19 at 16:12