JavaScript nullチェック


170

私は次のコードに遭遇しました:

function test(data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

私はJavaScriptに少し慣れていますが、ここで読んだ他の質問から、このコードはあまり意味がないように見えます。


特に、この回答では、

以外のコンテキストで未定義の変数にアクセスすると、エラーが発生しますtypeof

更新:上記の(の引用)答えは誤解を招く可能性があります。«未定義の変数»ではなく、« 宣言されていない変数»と表示する必要があります。

私が知ったように、Ryan♦maerics、およびnwellnhofの回答では、関数に引数が指定されていない場合でも、引数の変数は常に宣言されています。この事実は、以下のリストの最初の項目が間違っていることも証明しています。


私の理解では、次のシナリオが発生する可能性があります。

  • 関数が引数なしで呼び出されたためdata、未定義の変数が作成され、でエラーが発生しましたdata != null

  • この関数は、引数としてnull(またはundefined)を指定して具体的に呼び出されました。この場合data != null、内部コードはすでに保護されているため、&& data !== undefined役に立たなくなります。

  • 機能は、それが自明の両方を渡します。その場合にはnull以外の引数、と呼ばれていたdata != null data !== undefined

Q:私の理解は正しいですか?


私はFirefoxのコンソールで以下を試しました:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

data !== undefined アフター data != nullがなんの役にも立たないのか分かりません。


9
だけを使用してくださいif (data)。これは、data変数がtrueと評価されるかどうかをチェックするニーモニックなJavascriptの方法です。undefinednull偽、0、falseになしプロパティ評価すると、空の文字列、空の配列と(?)オブジェクトは、残りは真です。
J0HN 2013年

20
@ J0HN-を使用if(data)すると、彼はに、falseまたはの0値として渡すことができませんdata
techfoobar 2013年

@ J0HNまた、私が言及した同じ回答は、次のようif(typeof someUndefVar == whatever) -- worksにも述べていますif(someUnderVar) -- error
afsantos 2013年

2
おそらくことになっているdata !== null && data !== undefinedと等価である、data != nullと等価ですdata != undefined。それは条件についてより明確だとして、それは両方のことを見落とすことは容易になるだろう前者の形式は、好まれる傾向があるnullundefined、後の二つの条件で確認されています。
zzzzBov 2013年

2
ちなみに、の明示的なテストはundefined、IMOコードのにおいです。これはのような保護されたキーワードではなく、nullたまたま未定義の変数です。これは完全に有効であり、コードを壊します:undefined = 1
Izkata

回答:


106

「未定義の変数」は値とは異なりますundefined

未定義の変数:

var a;
alert(b); // ReferenceError: b is not defined

値を持つ変数undefined

var a;
alert(a); // Alerts “undefined”

関数が引数を取る場合、その値がundefinedであっても、その引数は常に宣言されるため、エラーは発生しません。しかし、あなたは正しいのですが、!= nullその後!== undefinedは役に立たなくなります。


32
data !== null && data !== undefinedしかし、理にかなっています。
bfavaretto 2013年

@bfavaretto:ええ、それは実際にはタイプミスかもしれません。しかし、あなたは決して知りません…:D
Ry-

1
思ったとおり、説明してくれてありがとう。また、それはタイプミスではないと思います。スクリプト全体で検索とカウントを実行したところ、10件のオカレンスが見つかりました。そのため、作成者もこれについて明確にする必要があると思います。
afsantos 2013年

2
上記の私のコメントをスクラッチします。実際にdata != nullは、nullandの両方をチェックしますundefined(興味深いことに、nulland だけをチェックしundefined、他の偽の値はチェックしません)。
bfavaretto 2013年

90

JavaScriptでは、null「値なし」のシグナリングに役立つ特別なシングルトンオブジェクトです。比較によってそれをテストできます。JavaScriptでは通常のように、===演算子を使用して型の強制を混乱させないようにすることをお勧めします。

var a = null;
alert(a === null); // true

@rynahが述べているように、「未定義」はJavaScriptで少し混乱します。ただし、typeof(x)「x」が宣言された変数でなくても、文字列が「undefined」であるかどうかをテストすることは常に安全です。

alert(typeof(x) === 'undefined'); // true

また、変数が初期化されていない場合、変数は「未定義の値」を持つ可能性があります。

var y;
alert(typeof(y) === 'undefined'); // true

まとめると、チェックは次のようになります。

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

ただし、変数「data」は正式な関数パラメーターであるため常に定義されているため、「typeof」演算子を使用する必要はなく、「未定義の値」と直接比較しても安全です。

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

このスニペットは、「関数が定義されており、nullではない引数で呼び出された場合...」と言っています。


5
なぜそれそのように見えるのですか?およびを!= null除くすべての値でtrueにnullなりundefined、この変数が宣言されていることを確認します。typeof他の状況では危険でさえあり得ます—変数名を誤ってタイプするとどうなりますか?エラーがないため、長い間検出されない可能性があります。
Ry-

@maericsしたがって、上記のシナリオのようなnullチェックで正しく答えた場合!=、厳密な比較だけを使用し!==ますか?
afsantos 2013年

@rynah:私は、nullテストが適切であるかどうかを知るために、OPの全体的なソリューションについて十分に知っているとは思いませんが、「typeof」を使用する必要がないという事実を言及するために編集しました。
maerics 2013年

@afsantos:実際には、多くの(何か?)値がnullに変換されるとは思いません。ただし、===実際に何をしているかを理解していて変換後の比較が必要でない限り()、厳密な比較()を使用することをお勧めします==
maerics 2013年

1
@Izkata:再定義を試みるライブラリを削除しundefinedます。また、iPad上のSafariは、いかなる状況でもそれを行いません。あなたもできませんdelete window.undefined
Ry-

10

あなたのケースで使用してくださいdata==null(これはnullと未定義の場合にのみ真です-2番目の画像では行/列のnull-undefinedに焦点を当てます)

ここにすべてがあります(src):

もし

ここに画像の説明を入力してください

==(その否定!=

ここに画像の説明を入力してください

===(その否定!==

ここに画像の説明を入力してください


8

Q:関数が引数なしで呼び出されたため、データが未定義の変数になり、データでエラーが発生しました!= null。

A:はい、data未定義に設定されます。仕様のセクション10.5宣言バインディングのインスタンス化を参照してください。ただし、未定義の値にアクセスしてもエラーは発生しません。エラーを発生させるストリクトモードで宣言されていない変数にアクセスすることと、これを混同している可能性があります。

Q:関数は、引数としてnull(またはundefined)を指定して呼び出されました。この場合、data!= nullはすでに内部コードを保護しており、&& data!== undefinedは役に立たなくなります。

Q:関数がnull以外の引数で呼び出されました。その場合、data!= nullとdata!== undefinedの両方が簡単に渡されます。

A:正解です。次のテストは同等です。

data != null
data != undefined
data !== null && data !== undefined

仕様のセクション11.9.3抽象等値比較アルゴリズムセクション11.9.6厳密等値比較アルゴリズムを参照してください。


宣言されていない変数と混同していませんでした。引数が指定されていない場合の動作を知りませんでした。にdata設定されるのではなく、まったく存在しないことを確信しましたundefined。明確化に感謝します。これらの参照は、両方の平等がどのように機能するかをより詳しく理解するのに役立ちました。
afsantos 2013年

3

変数を期待しない値でテストすることは、一般的に良い考えではないと思います。テストはあなた自身なので、禁止された値のブラックリストを書くと考えることができます。しかし、すべての禁止値をリストするのを忘れた場合はどうなるでしょうか。誰かが、あなたであっても、予期しない値を渡してコードを解読する可能性があります。したがって、より適切なアプローチは、ホワイトリストのようなものです-予期しない値ではなく、期待される値に対してのみ変数をテストします。たとえば、データ値が次の代わりに文字列であることが予想される場合:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

次のようなことをしてください:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}

2

typeof foo === "undefined"とは異なりfoo === undefined、決して混同しないでください。typeof foo === "undefined"本当に必要なものです。また、!==代わりに使用!=

したがって、ステートメントは次のように書くことができます

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

編集:

foo === undefined宣言されていない変数には使用できません。

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}

1
わかりましたが、この場合変数が宣言されているので、問題は何ですか?
Ry-

個人的にはfoo === undefined危険だと思います。これにより、防止しようとしていた同じ条件でコードが失敗します。

問題の関数の引数について話している。私の他のコメントも参照してください。
Ry-

1
なぜこれが反対票を投じられるのか‽最初の文は正確で重要な区別です!
イズカタ2013年

1
@Izkata:最初のステートメントの説明がないため。foo === undefinedOPの状況では完全に許容されます(undefinedオーバーライドされていないと想定)。答えは、なぜの !==代わりに使用する必要があるのについても説明していません!=
マット

1

テストを行う簡単な方法は次のとおりです。

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}

5
このテストはコンテキスト依存ではありませんか?つまり、の期待される型dataが文字列である場合、このテストは空の文字列に対してfalseを返します。これは適切な場合とそうでない場合があります(関数が空の文字列を何らかの方法で処理する場合があります)。
afsantos 2013年

5
ただし、「データ」に値""または0or NaN(またはその他)の値がある場合、「if」ブロックはスキップされます。これは、OPの意図である場合とそうでない場合があります。
maerics 2013年

@afsantosさん、申し訳ありません。コメントが表示されませんでした。データが未定義のときにfalseにしたい場合は、null ...日付が空の場合を除いて、他のvar toTest = dataを作成する必要があります。:のような最初のものの後に他の試験とIF(toTest ==「」){//ここにいくつかのコード}
Kadiri

-5
var a;
alert(a); //Value is undefined

var b = "Volvo"; 
alert(b); //Value is Volvo

var c = null;
alert(c); //Value is null

4
これが何を意味するのかについて説明を追加してください。
Ry-

これは実際にはありませんチェックのためにnull
user4642212 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.