前提・実現したいこと
Javascriptで比較演算を行う時、型変換を行わせず厳密な比較を行わせたいと思っています。
例として、文字列リテラル"2"と、数値リテラル1を比較させた場合、falseを出力させたいです。
下記はあくまで例です。このような比較演算子はないようです。
console.log("2" >== 1) # -> falseにしたい
発生している問題・エラーメッセージ
MDNを参照し、またChromeの開発者ツールのコンソールやNode.js(v9.8.0)で動作を確認してみたところ、等価演算子は厳密な演算子が用意されていますが、比較演算子は厳密なものが無いように見受けられます。
node
1> "2" >= 1 2true 3> "2" >== 1 4... # 入力待ちのままです
Chrome
1"2" >== 1 2VM488:1 Uncaught SyntaxError: Unexpected token =
試したこと
一つ前にtypeofを噛ませて、その上で比較するしか無いでしょうか。
node
1> a = "2" 2'2' 3> typeof a === typeof 1 && a >= 1 4false
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
不等号を含む比較で厳密比較する仕組みは、私が知る範囲にはありません。
対策は2つ考えられます。
対策1. 型変換を許容する
ECMAScriptはあらゆる場所で型変換が働くので、型変換ルールを覚えて許容するのが最もローコストだと思います。
対策2. 型を強制する
前提として、Number型が求められる変数に String 型が代入される状況が好ましくないと私は思います。
変数に求められるのがNumber型なら、どんな過程を辿ったとしても、必ずNumber型になるのが理想的です。
JavaScript
1const number = typeof foo === 'number' ? foo : NaN;
このように書けば、Number型以外をセットしようとした時には NaN
値か代入され、比較演算子の評価値は必ず false になります。
ECMAScriptでは、変数の初期化処理に干渉は出来ませんが、プロパティに干渉する事は出来ますので、適宜活用する事をお勧めします。
- setterで型変換後にセットし、getterで値を返す
- new Proxy で代入時に型変換する
組み合わせ方は様々ですが、私は「class + WeakMap + getter,setter」を好んで使っています。
さすがに、Number以外を禁止する型変換は実装したことがありませんが…。
場合によっては、TypeError
で強制終了させることも視野に入ります。
JavaScript
1throw new TypeError(arg + ' is not a Number')
Re: uS_aito さん
投稿2019/08/08 03:49
総合スコア18162
0
想像どおりJavaScriptという動的型付け言語の思想の話で
>==
という演算子は存在しません。
型変換を行わせず厳密な比較を行わせたいと思っています。
何がどうなって数字のStringと数値を衝突させなければならないのでしょうか?
こういう型が混入してしまうこと場面を考えた時、
基本的には以下の2パターンしか存在しえません。
- ユーザーからの入力値
→ そもそも何入力してもString型だよね、型変換試みて文字列なら例外投げよう
- Ajax等で受け取った後付のデータ
こういう所はしっかりバリデート掛けてからハンドリングしてやれば>==
演算子が欲しいという場面には遭遇しません。
上流工程を見直しましょう…というのがベストプラクティスになります。
もしエンジニアの技量差が激しい職場であれば、
思い切ってJavaScriptを捨ててTypeScriptでやるという手もあります。
コーディングルールでAny型を使うな!!みたいなルールを作れば
String型とNumber型を比較しなければならないという場面にたどりつくことすらなくなります。
TypeScriptはフロントエンドの世界で結構人気があるので、
良いエンジニアを採用するためのアプローチにもなるでしょう。
それを踏まえた上で「やだやだバリデーションはめんどくさい!」というなら、
質問文のように一度噛ませるしかありません。
全体的にそのような形式になっているのであれば、関数作って対処という形になるでしょう。
関数名はシェルスクリプトに良い名称があったので持ってきました。
JavaScript
1const ge = (a, b) => 2 typeof a == "number" && 3 typeof b == "number" && 4 a >= b; 5const gt = (a, b) => 6 typeof a == "number" && 7 typeof b == "number" && 8 a > b; 9const le = (a, b) => 10 typeof a == "number" && 11 typeof b == "number" && 12 a <= b; 13const lt = (a, b) => 14 typeof a == "number" && 15 typeof b == "number" && 16 a < b; 17 18console.log(ge(3, 2)); // true 19console.log(ge("3", 2)); // false
投稿2019/08/08 02:57
総合スコア21158
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
~~ECMAScriptの>=
の定義は、「左式 < 右式」の結果がtrue
かundefined
のときにfalse
、そうでない時にはtrue
、というものなので、左式にundefined
を返せればショートカットできます。
~~
If r is true or undefined, return false. Otherwise, return true.
ECMAScript® 2020 Language Specification
たとえば、以下のとおり。
js
1a = "2"; 2( a.toFixed && a ) >= 1 3/* 4false 5*/ 6 7a = 2; 8( a.toFixed && a ) >= 1 9/* 10true 11*/
もちろん、可読性に問題があるとは思いますが。
投稿2019/08/08 05:01
編集2019/08/08 05:03総合スコア36115
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/08 05:02
2019/08/08 05:07
0
一つ前にtypeofを噛ませて、その上で比較するしか無いでしょうか。
parseInt()するというのもありです。
型変換してしまっていて要件に合わないので削除。スルー願います。
投稿2019/08/08 02:26
編集2019/08/08 02:37総合スコア80850
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/08 02:34
2019/08/08 02:36
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/08 04:56