-1

I am pretty new to Javascript and have a beginner question in regards to declaring and accessing variables. Why does the console.log show me that the textContent of "text" has been changed when it hasn't? I can get the function to work if I instead of declaring "text" OUTSIDE of the function declare it inside - then the actual textContent change

let text = document.querySelector("#text").textContent

function changeText() {
  text = "Goodbye"
}

changeText()
console.log(text)
<p id="text">Hi</p>
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Dohjo
  • 13
  • 2
  • Are you asking why `text` is not a reference to `document.querySelector("#text").textContent`? – jabaa Nov 07 '21 at 19:15
  • _"I can get the function to work if I instead of declaring 'text' OUTSIDE of the function declare it inside - then the actual textContent change"_ That's not true: https://jsfiddle.net/7h2ej3L1/ – jabaa Nov 07 '21 at 19:21
  • @jabaa I guess I am yeah! If I declare "let textElement = document.querySelector("#text").textContent" inside of the function, it lets me change the textContent but not when I declare it outside. Btw: changed the variable name to textElement for clarification – Dohjo Nov 07 '21 at 19:26
  • _"If I declare '`let textElement = document.querySelector("#text").textContent`' inside of the function, it lets me change the textContent but not when I declare it outside."_ That's not true. I posted a link in my comment that proves you're wrong. – jabaa Nov 07 '21 at 19:27
  • @Dohjo I changed it back to `text` as otherwise that would a) invalidate existing answers b) introduce an inconsistency as you still did `console.log(text)` – Bergi Nov 07 '21 at 19:31
  • @Bergi And probably it's important that the variable name and the element ID are the same for this question. Because if `text` is declared inside the function and accessed outside the function, it will access the actual HTML element with this ID (in most current browsers). – jabaa Nov 07 '21 at 19:32
  • @jabaa I didn't want to open [that can of worms](https://stackoverflow.com/q/3434278/1048572) because `let text` should actually shadow the `window.text` element just fine, I don't thin there's a problem here. (I had assumed that when OP said "move the declaration inside the function", they'd move the `console.log` as well) – Bergi Nov 07 '21 at 19:34
  • @Bergi I think that's the actual problem here but OP didn't provide a reproducible code. I guess OP is accessing the HTML element through its ID by accident. As you can see in the JSFiddle in my comment, the `console.log` prints the HTML element, because I moved the declaration into the function. _"I can get the function to work if I instead of declaring "text" OUTSIDE of the function declare it inside - then the actual textContent change"_ doesn't make sense. – jabaa Nov 07 '21 at 19:35

2 Answers2

5

This assignment:

let text = document.querySelector("#text").textContent

stores a copy of the value of document.querySelector("#text").textContent in text. The is no explicit or implicit connection between text and document.querySelector("#text").textContent. You know have two places that happen to contain the same value.

You then proceed update one of the places to contain a different value:

text = "Goodbye"

This has no effect on the other place whatsoever.

This is also isn't specific to the DOM. That's the case with variables and/or properties in general. Here are some more examples:

var a = 1;
var b = a;
a = 2;
console.log('a:', a, 'b:', b);
b = 3;
console.log('a:', a, 'b:', b);

var a = {content: 1};
var b = a.content;
a.content = 2;
console.log('a:', a, 'b:', b);
b = 3;
console.log('a:', a, 'b:', b);

The technical term for this is pass-by-value: If you assign/pass a memory location A (variable, property, etc) to memory location B, then B is assigned a copy of the value of A, not a reference or pointer to A.

See also Is JavaScript a pass-by-reference or pass-by-value language?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

When you initialize your text variable at the top you’re setting its value to “Hi” (because that’s the textContent of your element) but it’s a copy of the value, completely independent of the DOM element. Changing one has no effect on the other.

So when you then update it (via text = “Goodbye”) you’re just changing the value of the variable, not the DOM element.

ray
  • 26,557
  • 5
  • 28
  • 27