JavaScriptの条件分岐で否定条件「!」ってよく見かけますが何となく「〇〇ではない」みたいな覚え方していませんか?
自分も最初プログラミングを勉強し始めたときに数学に近しいものを感じたので、ベン図を頭でイメージしてざっくりと理解しました。
もし駆け出しの方がご覧になっているのであれば「〇〇ではない」で一旦は覚えてもらっても大丈夫です。
とはいえ正しい意味を理解していないと後でエラーに遭遇するかもしれません。
「ググると(!)が出てくるけど何をやっているか分からない」
「条件分岐は簡単なものしか使えなくて、調べて出てきた記事の内容が理解できない」
今回は謎多き「!」について深堀していきます。
また動画もあるので適時使ってください。
JavaScriptの「!」が何をしているのか?
先に公式ドキュメントを紹介します。
以下のサイトが公式になっていますので一度目を通してみてください。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_NOT
「ちょっと難しいな」と思われたかもしれませんが、一番大事な部分はこちらになります。
「ある値が true
に変換できる場合、その値は真値 (truthy) と呼ばれます。ある値が false
に変換できる場合、その値は偽値 (falsy) と呼ばれます。」
とはいえ何言ってるか分かりませんよね。
以下のコードを見てみましょう。
const text = "入力しています";
// textに文字が入力されているかチェックしたい
if(!text){
console.log("NG");
}else{
console.log("OK");
}
// "OK"が出力される
textという変数に「何か文字があるか?」を条件分岐で判定しています。
if(!text)となっている部分が入力されていないパターンで、elseが入力されているパターンです。
上記のような書き方はググるとそれなりの頻度で見かけますが、1つ落とし穴があるんです。
const text = 0;
// textに文字が入力されているかチェックしたい
if(!text){
console.log("NG");
}else{
console.log("OK");
}
// "NG"が出力される
上記のように「0」が来ると”NG”の方を通してしまいます。
これが先ほど紹介した一文の部分になります、もう一度紹介します。
「ある値が true
に変換できる場合、その値は真値 (truthy) と呼ばれます。ある値が false
に変換できる場合、その値は偽値 (falsy) と呼ばれます。」
ある値は例題でいう「text」になります。
「!text」なので「text」がfalseに変換できる場合はfalseを呼びます。
そしてfalseに変換できるのは以下の5つと決められていて、先ほどは「0」を入れたのでfalseになったというわけなんです。
null
NaN
0
- 空文字列 (
""
または''
または``
) undefined
今回の例題では「0」も文字としてOKとしたいところですが「!」の原則から行くと上手く動作してくれません。
nullであるかを判定してみる
さて困りましたね、少し方法を変えてみようと思います。
「文字が入力されているか」なので言葉に従って「nullであるか」という形で以下のように書き換えてみました。
const text = 0;
if(text === null){
console.log("NG");
}else{
console.log("OK");
}
// "OK"と出力される
「0」も”OK”として動作するようになりました。
しかし残念ながらこちらも1つ問題があるんです。
例えば空文字(“”)を入れてみましょう。
const text = "";
if(text === null){
console.log("NG");
}else{
console.log("OK");
}
// "OK"と出力される
なんと今度は空文字が”OK”になってしまいました。
実はこちらの方が理由は簡単で「text === null」なので「nullかどうか?」ということで、空文字はnullではありませんので”OK”の方に行ってしまったんですね。
では続いて「text === “”」を条件にしたいところですが、そうすると先ほどの逆でnullが”OK”になってしまいます。
「||」を使ってみる
ここで新しい「||」という記号を使ってみたいと思います。
「論理和」と呼ばれてザックリいうと英語でいう「or」みたいなことになります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR
それでは以下のように修正してみましょう。
const text = "text";
if(text === "" || text === null){
console.log("NG");
}else{
console.log("OK");
}
// null、空文字が"NG"になり、0は"OK"になる
「text === “” || text === null」とすることで、「空文字もしくはnull」という意味になりました。
よって空文字とnullは”NG”となり、「0」を含む文字が入っていると”OK”にすることができました。
少しだけコードが長くなりましたが、「!」の隠れた挙動に対策できています。
「!」はシンプルなので便利なのですが、今回のような状況だと思ったような動きにならなくなるので注意しましょう。