Home > Enterprise >  Store a variable by reference in JavaScript
Store a variable by reference in JavaScript

Time:01-14

let myDivContent = document.querySelector(".myDiv").innerHTML;
myDivContent  = "Hello";

myDivContent appears to be a variable that contains the content of the div. Is it possible for it to hold a reference to the innerHTML of the div in order for the code above to work as intended?

CodePudding user response:

document.querySelector(".myDiv").innerHTML doesnot holds a reference to the html content, instead it returns the a string that contains HTML serialization of the element's descendants.

So you cannot use like myDivContent = "Hello";.

The better apprach is to hold your selector in a variable and update its value as

let myDiv = document.querySelector(".myDiv");
myDiv.innerHTML  = "Hello";

Here the variable myDiv holds a reference to the selector, hence you can update the innerHTML like above

CodePudding user response:

The magic of a "reference" can only be accomplished by a shared variable, property name or by a closure.

A closure is the only thing that can really do a reference the way you are imagining it. You'd need two functions. One for getting and one for settings:

  • get: () => thing
  • set: value => thing = value

This creates a "reference" to thing in the way that you are thinking.

The other issue is that = requires us to to get and set the same value, so we'll need to use a property to achieve that. But properties need an object, you can't just have a bare property. So let me describe a few approaches:

Approach 1 - no closure

Here's one way you could use a property to create an object that refers indirectly to some other object (without a closure). Properties allow you to use the = syntax to modify an arbitrary value such as a string the way you demonstrated.

I'll define the reference to be an object and a property of that object.

class Ref {
  constructor(obj, prop) {
    this.obj = obj;
    this.prop = prop;
  }
  get value() {
    return this.obj[this.prop];
  }
  set value(val) {
    return this.obj[this.prop] = val;
  }
}

const person = { greeting: "Hello" };
const ref = new Ref(person, 'greeting');
ref.value  = ' world';
console.log(person);

In the example above I've created an object { greeting: "Hello" } and stored it in a variable called person. Then I create a Ref that refers to that object and the greeting property name. You can say ref.value = 'something' because reading from ref.value calls the getter and writing to ref.value calls the setter. The = operator does both -- it reads and then writes, thus modifying the object.

This has limited flexibility and requires that you have an object and a property to refer to the thing that you want to be able to get/set.

Approach 2 - closure

The above Ref example is not flexible enough to refer to a local variable. For example, it doesn't have a way to modify the person variable, but it can modify the object that the person variable refers to. So, in general, if you need more flexibility, you could install properties on the fly and refer to the thing to be modified using a closure in the getter & setter with an arrow function like this:

var myLocalVariable = "Hello";
Object.defineProperty(this, "ref", {
  get: () => myLocalVariable,
  set: val => myLocalVariable = val
});
this.ref  = ' world';
console.log(myLocalVariable);

You can't have a bare property, though, so you'll have to assign the getter/setter to an object. You can use this like I did above, but in cases where that is inappropriate, you'll have to create your own object to hold the property.

Approach 3 - just keep it simple

In your case, you may want to just keep a reference to the element myDiv rather than to its content myDivContent. This is flexible enough to refer to any object (but not to a variable). That may be good enough for most cases.

let myDiv = document.querySelector(".myDiv");
myDiv.innerHTML  = " world";
<div >Hello</div>

  • Related