テーマ、知りたいこと
JavaScript の変数名について、
- HTML 要素が入っているのか?
- 他の何らかのデータが入っているのか?
の区別方法で困っています。
みなさんはどうやって区別していらっしゃいますか?
(これといった明白な正解はなさそうなので意見交換として投稿させて頂きました。)
具体的なコード
JavaScript
1// HTML要素 2const user = document.querySelector('.user'); 3 4// 他の何らかのデータ 5const user = { 6 id: 1, 7 name: 'Taro', 8 email: 'taro@example.com' 9}; 10 11// 変数名からは区別できず、意図しない動作を起こしがち 12console.log(user.name);
解決案
以下は素人の私なりに考えてみた解決案で、ChatGPT 曰く➀が良いらしいのですが、でも個人的には➁の方が短くて好きでして、困ってしまいました。
尚、要素取得においては document.querySelector()
をラップした次の $
を使っています。
JavaScript
1// 要素取得 2const $ = (selector, scope = document) => { 3 if (!scope) { 4 throw new Error("Invalid scope provided", { selector, scope }); 5 } 6 return scope.querySelector(selector); 7};
解決案➀
HTML 要素が入る場合は、接尾辞 *Element
をつける
JavaScript
1const getUserElement = (scope) => { 2 return $(`${scope} .user`); 3} 4 5const userElement = getUserElement("main");
解決案➁
HTML 要素が入る場合は、接頭辞 $*
をつける
JavaScript
1const get$user = (scope) => { 2 return $(`${scope} .user`); 3} 4 5const $user = get$user("main");
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答15件
#1
総合スコア117726
投稿2025/05/21 07:59
型を事前に確認するとよいのでは?
html
1<input class="user" name="hoge"> 2<script> 3const user1 = document.querySelector('.user'); 4const user2 = document.querySelector('.userx'); //該当がない 5const user3 = {name: 'fuga'}; 6if(user1 instanceof HTMLElement) console.log(user1.name); // hoge 7if(user2 instanceof HTMLElement) console.log(user2.name); 8if(user3 instanceof HTMLElement) console.log(user3.name); 9if(user1 === null) console.log(null); 10if(user2 === null) console.log(null); // null 11if(user3 === null) console.log(null); 12if(!(user1 instanceof HTMLElement) && user1 instanceof Object) console.log(user1.name); 13if(!(user2 instanceof HTMLElement) && user2 instanceof Object) console.log(user2.name); 14if(!(user3 instanceof HTMLElement) && user3 instanceof Object) console.log(user3.name); // fuga 15</script>
#2
総合スコア834
投稿2025/05/21 08:30
編集2025/05/21 10:09恐らくハンガリアン記法的な話だと思いますが...
js
1/ HTML要素 2const user = document.querySelector('.user'); 3 4// 他の何らかのデータ 5const user = { 6 id: 1, 7 name: 'Taro', 8 email: 'taro@example.com' 9}; 10 11// 変数名からは区別できず、意図しない動作を起こしがち 12console.log(user.name);
と書いてますが、まずそんな意味不明なコードを書くことがないのでは?
(これだとエラーになると思うのでスコープが違うのだと思いますが)
接頭辞として$をつけるのはありえますし、一般的だと思いますけど、
get$userはキモすぎる。
というかそもそも、独自フレームワーク的なのを使うのがキモイので、やめた方がいいと思います。
不具合修正とか、バージョンアップとかの業務は経験上ほとんど、独自フレームワークを使っていて、その会社が保守を放棄したものです。
それと、関数の命名についても、querySelectorでとってくること自体がgetなのかも甚だ疑問ではありますが。
どういう理由で何に困っているのか、ということ次第で対応方法は変わるでしょう。
共通のルールがある以外で、
変数名から区別して、意図した動作をできたぞ!って思うのがまず危険すぎると、私は思います。
ヘルパー関数を用意してログに書き込みたいとかじゃない限り中間関数を作成する意味も皆無だし、混乱の元にしかならない
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#3
総合スコア37438
投稿2025/05/21 09:16
これ、DOM要素に特有の問題なんでしょうか?
たとえば、ユーザーが作成するコンテンツを共有するサイト(teratailもそう)などで、ログインして閲覧しているユーザーとコンテンツを作成したユーザーが異なる場合など、user
という変数名をつけて取り違えるケースは普通にあり得ると思うのですが、特にDOM要素に対してケアをすべきと考えていらっしゃいますか?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#4
総合スコア86307
投稿2025/05/21 12:05
「変数名で、変数の中のデータが、DOM要素なのか、それ以外なのかの二択のどちらかが分かるようにしたい」ということなら、普通は変数名に固定文字列を付加するということになると思うので、「その文字列は何がいいか?」は単に好みの問題でどうでも良い話だと思います。個人開発なら自分で決めれば良いし、組織での開発なら組織内で相談する。書きぶりからは個人開発ですかね?
そもそも、「変数名で、変数の中のデータが、DOM要素なのか、それ以外なのかの二択のどちらかが分かるようにしたい」という考えを持つことが妥当なのか?という疑問もありますが、色々なことを考えて試行錯誤してみるのは成長に繋がるので、とりあえず思った方向に進んでみるのが良いかと思います。
質問からそれて、話を一般化すると、変数に入っているデータの意味を忘れてしまうような状態でプログラムを書いたり読んだりしているのであれば、そのこと自体が問題なので、「変数名と意味一覧」を作るとか、変数のスコープを把握できる程度に狭くするとか、IDEに支援してもらうとか、などでしょうか。
そうじゃなくて、さずがに意味は覚えているのだが、型(DOM要素なのか、それからデータを取り出してオブジェクト/辞書/ハッシュにしたものなのかなど)を忘れてしまうのが問題と言うこととであれば、書いているときのことであれば、変数に型のある言語に頼るのも一案です。また、IDEの使い方の工夫でもなんとかなるかも。いずれにしても本質的な解決ではないですが。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#5
総合スコア14330
投稿2025/05/21 13:58
変数見てどういうものかわかるようにしたいのであれば、「ハンガリアン記法的な話」との指摘があるように、説明的な名前、userBtn とか userInfo とかにするのがいいのではないかと思います。 批判されたりする手法ですが使いようだと思います。
また、そういう困難が発生するのは変数のスコープが広すぎるのではという指摘もそのとおりだと思いますが、やはり、そもそも変数名はその変数の役割を表わすようなものなので、それなりにより説明的な名前にしたほうがいいと思います。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#7
#1
yambejp さん
なるほど。変数名での区別ではなく操作前に型の確認ですか。
確実でいいかもしれません。
ありがとうございます。
そもそも変数名での区別なんて、みなさんあんまり採用しない感じなのですね。
#2
utm. さん
ハンガリアン記法という用語を知りませんでした。
おかげ様でこれにまつわる記述について一気に検索がはかどりそうです。
ありがとうございます。
独自フレームワーク的なのを使うのがキモイ
当質問においてフレームワークが何を指すのか理解ができない (フレームワークとは Laravel などような何か便利ソフト?みたいな認識?) なのですが、そもそも utm. さんからしてみれば質問のように変数名での区別はしないということでしょうか?
get$userはキモすぎ
やめておきますw
querySelectorでとってくること自体がgetなのかも甚だ疑問
これは意外です。要素取得系の関数を全て get で記述してしまいました。
何か妙案ございましたら教えて頂けませんでしょうか?
#3
Lhankor_Mhy さん
特にDOM要素に対してケアをすべきと考えていらっしゃいますか?
はい。DOM要素かそうでないか迷うことがよくあって、日ごろから問題視しています。
#4
otn さん
DOM要素なのか、それ以外なのかの二択のどちらかが分かるようにしたい」という考えを持つことが妥当なのか?
変数に入っているデータの意味を忘れてしまうような状態でプログラムを書いたり読んだりしているのであれば、そのこと自体が問題
みなさんきっと迷われていらっしゃるだろうと思っていました。
素人特有の感覚だったのですね。ありがとうございます。
#5
TakaiY さん
そういう困難が発生するのは変数のスコープが広すぎるのでは
やはりそうなのですね。悩みの方向性自体が怪しいのだと知れて良かったです。ありがとうございます。
#6
satoshih さん
おお、ありがとうございます。やはり変数名での区別という方向もありなのですね。
そしておすすめは userElement
ですか、なるほど、get$user
はやめておきます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#8
総合スコア21412
投稿2025/05/22 10:06
これは単に命名力の問題でしょう
js
1const user = document.querySelector('.user');
お前はDOMツリーから検索して引っ掛けてきたDOMじゃねえか!
どこがユーザーやねん
js
1const user = { 2 id: 1, 3 name: 'Taro', 4 email: 'taro@example.com' 5};
いやお前もオブジェクト初期化子で作られたオブジェクトだろ
ユーザーじゃないじゃないか
さて、変数ってのは基本的に中身に何があるか分からないおもちゃ箱のようなものです。
変数名がラベル。
おもちゃ箱にPlayStationやSwitch等のゲーム着を詰めたとします。
貴方がゲーム機をSwitchしか持っていないのであれば「ゲーム機」でも良いですよ。
ゲーム機=Switchだ!ってわかりますから。
しかしモンハンワイルズがしたくなってPS5を買ってきた。
更にSwitch2にも当選して買っちゃった。
そして「ゲーム機」というラベルが貼ってある3個のおもちゃ箱を前に
「何が入ってるか分からない……」と途方に暮れてるわけですよ。
アホちゃうか
コード内の変数というものは
「文脈」や「状況」で変わります。
user
と書いてある変数を前にして
「いやこれ、DOMツリーなのかオブジェクトなのかさっぱり分からん……」と唸ってしまうならば
もっと具体的な名前を足して区別するべきでしょう。
私のWebエンジニアとしての肌感覚としての指標を挙げるなら
document.querySelector('.user');
はDOMツリーですからね
混同してしまうのであれば、その変数スコープ内ではdomUser
みたいな変数名にしてしまうのは一つありだと思います。
ここから {id:1, name: "taro"}
を引っ張り出してくるのであれば source
という変数名に、
これに値を注入して画面を更新したいのであればdist
という変数名を指定してあげるのもありだと思います。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#9
総合スコア14330
投稿2025/05/22 10:41
編集2025/05/22 10:42意見を受けての質問者さんの回答を見ると、どういう方向で納得しているのかよくわかりませんね。
ざっと見ると、・変数名をもう少し説明的にする。 ・変数の数が多くならないようにスコープを狭くする=関数に分割する あたりが効果的なのではないこという感じだと思いますよ。
当質問においてフレームワークが何を指すのか理解ができない
ここで指摘されているフレームワークというのは、
要素取得においては document.querySelector() をラップした次の $ を使っています。
これのことだと思います。 $() が出てきたら、引数が示すのDOM要素だということですが、こういうのもフレームワークと言えます。一見、関数呼び出しには見えず、慣れると便利なのでしょうが、他の人が見るとびっくりするでしょうね。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#10
総合スコア834
投稿2025/05/22 10:42
編集2025/05/22 10:46#7さん
当質問においてフレームワークが何を指すのか理解ができない (フレームワークとは Laravel などような何か便利ソフト?みたいな認識?) なのですが、そもそも utm. さんからしてみれば質問のように変数名での区別はしないということでしょうか?
私が言っている、独自フレームワーク的なのというのは、
js
1// 要素取得 2const $ = (selector, scope = document) => { 3 if (!scope) { 4 throw new Error("Invalid scope provided", { selector, scope }); 5 } 6 return scope.querySelector(selector); 7};
のような、バニラの実装をラップして根底の処理を他の部分からこれを使うと定めた共通の処理が基準になったもののことです。
コード中にこの関数の使用が出てきたら、みんながそれを理解しているという前提になりますよね。
知らない人は一々このコードを理解するか、もしくはドキュメントを読むしかなくなります。
そもそも utm. さんからしてみれば質問のように変数名での区別はしないということでしょうか?
区別は必須ではないという意見です。$を接頭辞として使うのは一般的だと思っていますし、$をつけて区別してもいいし、しなくてもいいと思っています。
これは意外です。要素取得系の関数を全て get で記述してしまいました。
何か妙案ございましたら教えて頂けませんでしょうか?
その法則にしたがうのであれば、querySelectorというメソッドは本来getQuerySelectorのように接頭辞get
がついていないと不自然と思われているのですか?という話です。
例えばですが、#userというセレクタがあれば、userという変数名(プロパティ)がjsで自動で作られるみたいな、実装もありかもしれません。
しかし、そもそもですが
document.querySelector('.user')
と普通に書けば、すべてが解決しますよね。
console.log(document.querySelector('.user').name);
とすれば、何をしたいのか一目瞭然です。
で、大抵のプログラミング言語ではクラスやオブジェクトを定義してそれを名前空間的に使うことで値を管理するのですが、
jsのような画面ありきの言語ではそもそも画面の方に値があってそれを操作するというのが自然な言語設計上の発想になっているので、小さいプログラムで完結させることを前提のようにしています。(つまり、DOMや画面.値のような巨大なオブジェクトを参照の管理のために定義することを想定しておらず、画面(HTML)の方に既にあるじゃん。というのを前提にしているという話です。)
ですので、変数名のバッティングとか何が何を刺しているのか分からないとかは余りにも処理が複雑すぎるでしょうという話なので、
質問が起きた経緯、具体的に解決したい問題を明確にしてほしいというのが回答者側の意見になると思います。
画面に値があるということでそれとjsを紐づけるためのバインド処理的なものもありかもしれません。というのはつまりはそういうことで、あえて変素が変更されたりしないので、グローバルスコープで定義済みとするというのも考えられるという話です。
もし、極端に処理を分割したいとかそういう要望なのであればそれはもう完全に趣味の範疇の話にしかなりえないようにも思えます。
もしその認識があればそう明記してもいいのかもしれません。
そして、どのように勉強なさっているのか定かではありませんが、一連の処理に関してもしjqueryというライブラリを知らないのであれば、使用を検討してみてもよいかもしれません。
バニラを完璧に理解して自作フレームワークを作ってやるぞぐらいの勢いがあるのであれば、無理に使用は勧めませんが。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#11
#8
miyabi-sun さん
ああ、なるほど!そういう風に命名するのですね。
私はプロジェクト全体で「JSON 構造のユーザ情報を持つから userData
で、DOM だから userElement
」のように命名することを考えていました。スコープもファイルも超えて、プロジェクト全体での命名です。
(もちろん全てにグローバルな固有名詞をつけてしまうようではスコープやモジュールの意味がないので、DOM だけでも変数名を一瞥するだけで区別できた方が便利だと思うんだけどなぁというのが本旨ではございますが。)
でもそうではなくて、「ある文脈(ファイルまたはスコープ内)においては「ユーザにまつわる情報を持つ変数は1つしかないから user
とするけど、他の文脈においては DOM のものもあるので userData
と userElement
の2つ」のように命名する感じですね。
そういう風に「文脈でわかるでしょ」な姿勢でいくならば、なるほど、上記でみなさんが仰っていたことがやっと理解できました。ありがとうございます。
あれ?しかしその場合、下記のツッコミが理解できなくなります。
お前はDOMツリーから検索して引っ掛けてきたDOMじゃねえか
いやお前もオブジェクト初期化子で作られたオブジェクトだろ
いやそうつっこまれましても、その文脈においてそれしかなければ別に user
だけの変数名でいいのではないでしょうか?ゲーム機を1つか持っていないときのように。なぜつっこまれるのでしょうか?
「DOMじゃねえか」「オブジェクトだろ」に対しては、「文脈でわかるでしょ」と返されるハズなのではないでしょうか?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#12
総合スコア21412
投稿2025/05/22 11:59
#11
良い感じに伝わって良かったです。
この「現実世界に置き換えるとアホな事やってんなー」ってなるのは結構ありがちで、
私がプログラマー初心者の頃に苦労した体験から、こういう話をすれば良いかな?と思って書きました。
「DOMじゃねえか」「オブジェクトだろ」に対しては、「文脈でわかるでしょ」と返されるハズなのではないでしょうか?
ここはちょっと話が飛躍しまいましたね。
補足します。
結局超厳密に言い始めると、「userは一人の人間」であるはずですよね。
userって言いながらオブジェクトやDOMを持ってくるのは何?ってなっちゃうじゃないですか。
じゃあ変数名userって良くないよね。
全部の変数名を見直そうって話になると、
全部の変数がくっそ長い可読性の欠片もないコードになってしまう。
なので「この文脈に於いてuser
は1ユーザーの本システムで使いたい情報を持たせたオブジェクトかなぁ……」という決め打ちが必要になります。
こういう風に話の流れを持って行きたかったわけです。
なので冒頭の状態では「文脈でわかるでしょ」は省いて考えてください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#13
総合スコア86307
投稿2025/05/24 02:21
#4ですが、質問へのストレートな回答以外は短めに書いたので、一部誤解を与えたかも知れません。
みなさんきっと迷われていらっしゃるだろうと思っていました。
素人特有の感覚だったのですね。ありがとうございます。
「この変数なんだっけ?」は初心者だけでなく、中上級者でも感じることはあるかと思います。
変数宣言のある言語をエディターで編集しているときに、変数名にカーソルを置いてショートカットキーを押すとその変数の宣言箇所にカーソルが移動したりポップアップで見えたりするのも、そういうことの解決方法でしょう。
初心者的という意味で書いたのは、前回、
そもそも、「変数名で、変数の中のデータが、DOM要素なのか、それ以外なのかの二択のどちらかが分かるようにしたい」という考えを持つことが妥当なのか?
と書いた部分です。「二択なら案①でも案②でも好みの問題」と書きましたが、これが「XXなのか、YYなのか、ZZなのか、それ以外なのか四択で区別したい」になると、案②の延長で考えるのが難しくなります。
ただ、ここまで書いて、質問を読み直すと、「変数名ネーミングの一般論で、DOMのはあくまで一例」ではなくて、「DOMを扱うJavaScriptプログラム限定の局所的なケースについての質問」ですかね。であれば、二択限定の発想も納得できます。
私の場合は、「変数の意味は覚えているが、型が思い出せない。なので変数名で型さえ分かれば解決」と思ったことはなく、「変数に入っているデータの意味がすぐに思い出せない」は、日数が経つとしばしば感じるので、そちらの対策を考えるべきかと思って、前回の後半を書きました。
「型だけ忘れる」ケースにも有効かと思うので、もう少し書いておきます。
①変数名をしっかり考えて意味が分かるような変数名にする
⇒ 言わずもがなの正攻法だが、考えるのに時間が掛かるし、いくら考えても「これが唯一の正解」という名前は無い。まあ、これはしっかりやるべき。アプリケーションハンガリアンも検討。
②IDEなどのツールに頼る
⇒ 一例として、変数宣言の所に飛ぶ機能と、変数宣言の所に説明のコメントを書くこととの組み合わせなど。
③変数のスコープを狭くする
⇒ 有効なので無理の無い範囲でやればいいが、「全ての変数についてスコープを5行以下にする」とかはまず無理。
④変数の数を減らす
⇒ 変数は作らず、変数参照場所に式を直接書くとか。式を書く場所によって式の値が変わるかも知れないこともあるし、変数をつくるかどうかはメリットデメリットあるので毎回検討。#10のutm.さんの「しかし、そもそもですが」の部分も「そもそもその変数を作らない」という意味だと思います。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#14
#9
TakaiY さん
どういう方向で納得しているのか
私の疑問は「DOMの入った変数の区別」で、対するご回答の多くは「そんな区別は不要」でしたので、「そういうものなのか」と。
納得というよりはとりあえず言うこと聞いておこうと飲み込んだ感じでした。
しかし#8 の miyabi-sun さんのご回答のおかげで、「そんな区別は不要」について、「文脈でわかるでしょ」という理由からなのだと納得できました。
そのことは TakaiY さんも
変数の数が多くならないようにスコープを狭くする=関数に分割する あたりが効果的
と仰っている通りかと思います。
スコープを狭くし、その上で、「スコープ内で1つしかユーザを扱わなければ変数名は user でいい」し、「複数あればそれに応じて aaaUser, bbbUser などと分ければいい」のであって、「DOM ならそう区別する変数名を常につける・そんな区別は常に不要」という筋ではなかったということですね。
#10
utm. さん
フレームワークと聞くとなにか大規模な印象でしたが、その程度でも使う名前だったのですね。
それにしても個人開発においては便利だと思いすでにいろいろなフレームワークを作っちゃったのですが、今のうちに教えて頂き助かりました。
ありがとうございます。
変数名のバッティングとか何が何を刺しているのか分からないとか
質問が起きた経緯、具体的に解決したい問題
「何を指しているかわからなくなる」というほどではないのですが、「一瞥できないと一瞬迷う」という問題意識でした。
数行の文脈から判別するよりも、変数名だけで一瞥できた方が便利っぽいという考えです。
かといってすべてに長い説明的な変数名をつけてしまえば本末転倒なので、よく迷うDOMだけでも区別したいなと思っていました。
#12
miyabi-sun さん
いつも miyabi-sun さんのご回答はちょっと面白いメタファーがあって楽しく拝読させて頂いております。
すみません話の流れが読めていなかったですね。改めてご説明ありがとうございます。
#13
otn さん
「DOMを扱うJavaScriptプログラム限定の局所的なケースについての質問」ですかね
仰る通りです。質問が不明瞭でみなさんを迷わせてしまいました・・
IDEなどのツールに頼る
少し調べたらこれめっちゃ便利ですね!ありがとうございます。
よく引数で迷うのですが、引数なら JSDoc と呼ばれるコメントに明記できたり、かなり今後のためになりそうです。
その他の整理もありがとうございます。こういう筋を今のうちにある程度抑えておけるのはかなり有利に進めそうです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
#15
総合スコア21754
投稿2025/05/25 00:05
JavaScriptを窓から投げ捨てて、TypeScriptを使う。
以上です。
変数名をどうするのかという問題はコーディングスタイルなどにも通じる総合的な判断が必要な複雑な問題ですが、質問者がさんが解決したいのは、「変数が束縛しているオブジェクトは何か?」という話だけかと思います。確かに、ハンガリアン記法のように変数名に型を明記するという方法もありますが、よろしくない方法と考えている人も多いようです。
ということで、変数名の話はいったん置いておくとして、変数の型をすぐ知りたい、型の認識間違いでエラーになるのを防ぎたいというのであれば、話は単純です、静的型付けの言語を使えば良いのです。JavaScriptの代替としてはTypeScriptがあります。TypeScriptはJavaScriptに型定義等を追加しただけなので、JavaScriptを学んでいる人なら、簡単に乗り換えられるでしょう。TypeScriptと適切なエディター(VSCode等)やIDEを使っていれば、その変数の型はマウスカーソルを重ねるだけですぐにわかります。もし、勘違いしていたとしても、型違いのエラーメッセージがでるので、これまたすぐに気づけます。
かくいう私も、CoffeeScirptからCivetに乗り換えました。最初はちょっと苦労しましたが、型がある生活の安心感は一度始めたら止められません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。