0

HTML:

<h1 id="ws-title"></h1>
<time datetime="" id="ws-date"></time>

JS:

inp1 = document.querySelector("input[name='ws-date']");
out1 = document.querySelector("#ws-date");
inp1.addEventListener("input", e => {
        out1.textContent=e.target.value;
});

inp2 = document.querySelector("input[name='ws-title']");
out2 = document.querySelector("#ws-title");
inp2.addEventListener("input", e => {
        out2.textContent=e.target.value;
});

Works as expected (i.e: changing input changes corresponsing h2).

However:

function pairListen(name) {
    inp = document.querySelector(`input[name='${name}']`);
    out = document.querySelector(`#${name}`);
    inp.addEventListener("input", e => {
            out.textContent=e.target.value;
    });
}
pairListen("ws-title");
pairListen("ws-date");

Causes <h2 id="ws-date"> to be changed when <input name="ws-title"> is changed and vice versa.

Why is that? All difference is that repeated code is embedded in a function.

AvidSeeker
  • 97
  • 2
  • 10

1 Answers1

1

That's because when you declare a variable without a declarator (i.e. var, let, or const) it automatically gets defined in window, this, and globalThis (making those kinds of variables global, accessible anywhere in your code). The second time you do varName = "value";, you're not redeclaring the variable. You're modifying it. You can solve this by applying a declarator.

function pairListen(name) {
    const inp = document.querySelector(`input[name='${name}']`);
    const out = document.querySelector(`#${name}`);
    inp.addEventListener("input", e => {
            out.textContent=e.target.value;
    });
}
pairListen("ws-title");
pairListen("ws-date");
<h1 id="ws-title"></h1>
<input name="ws-title" />
<h2 id="ws-date"></h2>
<input name="ws-date" />

Moral of the story—always declare variables with declarators, or you'll encounter unprecedented results. You can force yourself to follow good style by adding "use strict"; to the top of all your JavaScript files, which will not tolerate writing code that will give you unexpected results.

code
  • 5,690
  • 4
  • 17
  • 39
  • 1) That's weird, doesn't javascript destroy variables after the scope ends?. 2) "it automatically gets defined...", as what by default? 3) in this case there is no difference between using any of `var, const, let`, am I correct? – AvidSeeker Feb 27 '22 at 01:03
  • @AvidSeeker 1: JavaScript destroys variables that have declarators at the end of a function. Variable declarations **without** declarators **immediately becomes globally scoped**, hence defined in window or `globalThis`. 2: It only gets defined if it wasn't defined before and if you're assigning a value to it (default value would be `undefined` or "ReferenceError", depending on how you use it). 3: The main difference is that it's illegal in strict JavaScript, and **most importantly** it gets defined in the global scope, `globalThis`. And yes, that makes it a huge difference. – code Feb 27 '22 at 01:08