0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

x=getElementByid("x")はやめよう

Last updated at Posted at 2022-11-22

getElementByIdと変数スコープ

簡単な3つの要素(input button, input text,div)をもち、ボタンが押されるとテキストボックの値をdivタグ内にコピーするHTMLとjavascriptがあるとします。

scope.html
<html>
<body>
    <input type="text" id="txt" />
    <input type="button" id="btn" value="Start" />
    <div id="lbl"></div>
    <script src="scope.js"></script>
</body>
</html>

scope.js(変数スコープエラーのあるプログラム)
const myfunc=()=>{
    //スコープ外からローカル変数参照するとエラー
    albl.innerHTML=atxt.value;
}
document.addEventListener("DOMContentLoaded", () => {
    const abtn = document.getElementById("btn");
    const atxt=document.getElementById("txt");
    const albl=document.getElementById("lbl");
    abtn.addEventListener("click",() => {
        myfunc();
    });
  });

上記のmyfunc関数はイベントハンドラ関数内のオブジェクト変数のスコープ外にあるので上記javascriptは正常に動作しません。教科書通りです。ところが以下のようにmyfunc関数内で参照する変数名の冒頭のaをとると

scope.js(動いてしまうプログラム)
const myfunc=()=>{
    lbl.innerHTML=txt.value;
}
document.addEventListener("DOMContentLoaded", () => {
    const abtn = document.getElementById("btn");
    const atxt=document.getElementById("txt");
    const albl=document.getElementById("lbl");
    abtn.addEventListener("click",() => {
        myfunc();
    });
  });

上記プログラムは動作します。DOMの要素のid名はそのままグローバルのオブジェクト変数として暗黙的に宣言されています。このため、下記プログラムのようにイベントハンドラ内からもの冒頭のaをとると、スコープ外のmyfuncからイベントハンドラ内のローカル変数が参照できたように見えます。教科書に書いてあることが嘘に見えるコードです。

scope.js(動く上に変数スコープを破壊したように見えるプログラム)
const myfunc=()=>{
    //スコープ外からlblやtxtを参照できたように見える
    lbl.innerHTML=txt.value;
}
document.addEventListener("DOMContentLoaded", () => {
    const btn = document.getElementById("btn");
    const txt=document.getElementById("txt");
    const lbl=document.getElementById("lbl");
    btn.addEventListener("click",() => {
        myfunc();
    });
  });

それならgetElementByIdを使わず、全部グローバル変数を参照した方が潔いのでしょうか。

scope.js(getElementByIdを使わない動作するプログラム)
const myfunc=()=>{
    lbl.innerHTML=txt.value;
}
document.addEventListener("DOMContentLoaded", () => {
    btn.addEventListener("click",() => {
        myfunc();
    });
  });

いずれにせよ下記のようなid名と変数名を一致させたgetElementByIdは無駄でスコープを破壊したように見えるコードができるので、やめた方が良いのでは、というお話です。

x=getElementById("x");
scope.js(暗黙のグローバル変数を使わないコード)
document.addEventListener("DOMContentLoaded", () => {
    const abtn = document.getElementById("btn");
    const atxt=document.getElementById("txt");
    const albl=document.getElementById("lbl");
    const myfunc=()=>{
        albl.innerHTML=atxt.value;
    }
    abtn.addEventListener("click",() => {
        myfunc();
    });
  });
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?