未定義のオブジェクトプロパティの検出


回答:


2680

プロパティの値が特別な値であるかどうかを確認する通常の方法は、undefined次のとおりです。

if(o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

オブジェクトが実際にそのようなプロパティを持たないかどうかをチェックし、したがってundefined、アクセスしようとするとデフォルトで返されます。

if(!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

識別子に関連付けられた値が特別な値undefinedであるどうか、またはその識別子が宣言されていないどうかを確認します。注:このメソッドは、宣言されていない(注:の値を持つのとは異なるundefined)識別子を早期エラーなしで参照する唯一の方法です。

if(typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

ECMAScript 5より前のバージョンのJavaScriptでは、グローバルオブジェクトの "undefined"という名前のプロパティは書き込み可能だったため、foo === undefined誤って再定義された場合、単純なチェックが予期せず動作する可能性があります。最新のJavaScriptでは、このプロパティは読み取り専用です。

ただし、最新のJavaScriptでは、「未定義」はキーワードではないため、関数内の変数に「未定義」という名前を付けて、グローバルプロパティを隠すことができます。

この(ありそうにない)エッジケースが心配な場合は、void演算子を使用して特別なundefined値自体を取得できます。

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}

9
何かがnullの場合、それは(nullとして)定義されますが、あまりにもチェックを活用できます。上記のコードの厄介な詳細は、それをチェックする関数を定義できないことです。まあ、関数を定義することはできますが、それを使用してみてください。
neu-rah 2012年

5
@ neu-rah関数を記述できないのはなぜですか?なぜこのようなものではないのですか?それは私のために働くようです。私が考慮していないケースはありますか?jsfiddle.net/djH9N/6
Zack

7
@Zack isNullorUndefinedのテストでは、isNullOrUndefined(f)を呼び出し、fが宣言されていない場合(つまり、「var f」宣言がない場合)は考慮されませんでした。
pnkfelix

109
ほら、今数千票。これは、これを行うために考えられる最悪の方法です。通行人がこのコメントを見て、他の答えをチェックすることを願っています…
Ry-

17
obj !== undefined今すぐ使えます。興味深い結果をもたらすもののundefinedように、以前は変更可能undefined = 1234でした。しかし、Ecmascript 5以降は、書き込み不可になったため、より単純なバージョンを使用できます。codereadability.com/how-to-check-for-undefined-in-javascript
Bruno Buccolo 2016年

899

このトピックには多くの不正解があると思います。一般的な考えに反して、「未定義」はJavaScriptのキーワードではなく、実際には値を割り当てることができます。

正しいコード

このテストを実行する最も堅牢な方法は次のとおりです。

if (typeof myVar === "undefined")

これは常に正しい結果を返し、myVar宣言されていない状況にも対応します。

縮退コード。使ってはいけません。

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

さらに、myVar === undefinedmyVarが宣言されていない状況ではエラーが発生します。


133
myVarが宣言されていない場合、myVar === undefinedがエラーを引き起こすことに注意して+1
Enrique

73
私はここで与えられた最初の正当化を=== undefined困惑させないために見つけます。はい、あなたはに割り当てることができますが、そうするundefined正当な理由はなく、そうすることはあなたのコードを壊すかもしれないと予測できます。Cでは次のことが可能#define true false、とPythonであなたがに割り当てることができるTrueFalse、人々は意図的にコードの他の場所で、自分の環境を妨害自身の可能性から保護するように、これらの言語でのコードを設計する必要性を感じていません。undefinedここで検討する価値さえあるのになぜ割り当てられる可能性があるのですか?
Mark Amery 2013年

19
Marksのコメントに加えて、「myVar === undefinedは、myVarが宣言されていない状況でエラーを発生させます。」というコメントは得られません。-なぜこれが悪いのですか?宣言されていない変数を参照している場合、エラーが発生したくないのはなぜですか?
eis

5
またvoid 0undefinedポイントする値を取得するためにいつでも実行できることを覚えておいてください。そうすることができますif (myVar === void 0)。これ0は特別なことではなく、文字通り任意の式をそこに置くことができます。
Claudiu 2013年

28
最新のブラウザ(FF4 +、IE9 +、Chrome不明)では、を変更することはできませんundefinedMDN:未定義
user247702

228

ここで他の多くの回答によって激しく推奨されているにもかかわらず、typeof は悪い選択です。undefinedundefinedと変数が存在するかどうかの複合チェックとして機能するため、変数が値を持っているかどうかのチェックには使用しないでください。ほとんどの場合、変数がいつ存在するかがわかっているのでtypeof、変数名や文字列リテラルにタイプミスをすると、暗黙の失敗が発生する可能性があります'undefined'

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

したがって、特定の名前がスコープ内にあるかどうか(typeof module !== 'undefined'CommonJS環境に固有のコードのステップとしてチェックするなど)が不確かな機能の検出²を行わない限りtypeof、変数で使用する場合は有害な選択であり、正しいオプションは値を直接比較するには:

var foo = …;

if (foo === undefined) {
    
}

これに関するいくつかの一般的な誤解は次のとおりです。

  • 「初期化されていない」変数(var foo)またはパラメーター(function bar(foo) { … }、と呼ばれるbar())の読み取りは失敗します。これは単に真実ではありません。明示的な初期化のない変数とundefined、値が指定されなかったパラメーターは常にになり、常にスコープ内にあります。

  • それはundefined上書きすることができます。これにはもっとたくさんあります。undefinedJavaScriptのキーワードではありません。代わりに、未定義の値を持つグローバルオブジェクトのプロパティです。ただし、ES5以降、このプロパティは読み取り専用になり、構成できなくなりました。最新のブラウザーではこのundefinedプロパティを変更できません。2017年の時点で、これは長い間当てはまっていました。ストリクトモードがなくても、undefinedの動作には影響しませんundefined = 5。スローするのではなく、何もしないようなステートメントを作成するだけです。ただし、これはキーワードではないため、nameという名前の変数を宣言undefinedでき、これらの変数を変更して、かつて一般的なパターンを作成できます。

    (function (undefined) {
        // …
    })()
    

    より多くのグローバルを使用するよりも危険undefined。ES3互換にする必要がある場合は、に置き換えundefinedvoid 0くださいtypeof。(voidこれまで常に、任意のオペランドが未定義の値に評価される単項演算子でした。)

変数がどのように機能するかについては、実際の問題であるオブジェクトのプロパティに取り組む時が来ました。typeofオブジェクトのプロパティに使用する理由はありません。特徴検出に関する以前の例外はここでは適用されません。typeof変数に対して特別な動作があり、オブジェクトプロパティを参照する式は変数ではありません。

この:

if (typeof foo.bar === 'undefined') {
    
}

、常に正確同等 this³へ:

if (foo.bar === undefined) {
    
}

上記のアドバイスを考慮に入れて、を使用している理由について読者を混乱させないようにしてください。typeofこれは、===変数の値を後でチェックするようにリファクタリングできるため、見栄えが良いので、常に=== undefinedここでもuseを使用する必要があります

オブジェクトのプロパティに関して他に考慮すべきことは、本当にチェックしたいかどうかですundefined。特定のプロパティ名は、オブジェクトに存在しない(undefined読み取り時に値を生成する)か、オブジェクト自体にvalue undefinedと存在するか、オブジェクトのプロトタイプにvalue undefinedと存在するか、または値のないオブジェクトのいずれかに存在しundefinedます。'key' in objキーがオブジェクトのプロトタイプチェーンのどこかにあるかどうか、およびObject.prototype.hasOwnProperty.call(obj, 'key')オブジェクトに直接あるかどうかがわかります。ただし、プロトタイプや文字列キーマップとしてのオブジェクトの使用については、この回答では詳しく説明しません。これは、元の質問の考えられる解釈に関係なく、他の回答のすべての悪いアドバイスに対抗することを主な目的としているためです。よく読んでMDNのオブジェクトプロトタイプの詳細!

例の変数名の変わった選択?これは、FirefoxのNoScript拡張機能からの実際のデッドコードです。
²ただし、スコープ内にあるものを知らなくても大丈夫だとは限りません。動的スコープの乱用によって引き起こされるボーナスの脆弱性:Project Zero
1225³もう一度ES5 +環境を想定し、それundefinedundefinedグローバルオブジェクトのプロパティを参照します。void 0それ以外の場合は置き換えます。


@BenjaminGruenbaum真実だが完全に誤解を招く。デフォルト以外のコンテキストでは、デフォルトのコンテキストを非表示にして独自のを定義できますundefined。これは、ほとんどの実用的な目的で、上書きするのと同じ効果があります。
blgt 2014年

23
@blgtそれは偏執的であり、実用的なものには無関係です。すべてのコンテキストは、console.logをオーバーライドしたり、Arrayプロトタイプメソッドを再定義したり、Function.prototype.call`フックをオーバーライドしたり、JavaScriptで関数を呼び出すたびに変更したりできます。これからの保護は非常に偏執的で、ばかげています。私(およびミニテック)が言ったように、あなたはvoid 0未定義と比較するために使用できますが、それは愚かでやり過ぎです。
Benjamin

19
私は与えるために複数の賛成投票があったらいいのに。これが最も正解です。私typeof something === "undefined") はコードで見るのをやめたいです。
Simon Baumgardt-Wellander

@BenjaminGruenbaum怠惰なプログラマにとって、void 0(一度に)短く安全です!それは私の本での勝利です。
wizzwizz4 2018

4
これは本当に受け入れられる答えになるはずです。それは最も徹底的で最新のものです。
Patrick Michaelsen

161

JavaScriptにはnullundefinedがあります。彼らは異なる意味を持っています。

  • undefinedは、変数値が定義されていないことを意味します。値が何であるかは不明です。
  • nullは、変数値が定義され、nullに設定されている(値がない)ことを意味します。

Marijn Haverbekeは、彼の無料のオンラインブック「Eloquent JavaScript」で私の次のように述べています

同様の値nullもあり、その意味は「この値は定義されていますが、値がありません」です。undefinedとnullの意味の違いは、ほとんどが学術的なものであり、通常はあまり興味深くありません。実際のプログラムでは、何かが「価値がある」かどうかを確認する必要があることがよくあります。これらのケースでは、something == undefinedという式を使用できます。これは、それらがまったく同じ値でなくても、null == undefinedがtrueを生成するためです。

だから、私は何かが定義されていないかどうかを確認する最良の方法は次のようになると思います:

if (something == undefined)

お役に立てれば!

編集:編集に応じて、オブジェクトのプロパティは同じように機能するはずです。

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

42
if(something == undefined)はif(something === undefined)のように記述した方がよい
Sebastian Rittau 2009年

59
これは完全に安全ではないことを指摘しておく必要があります。undefinedユーザーが再割り当てできる変数にすぎundefined = 'a';ません。書くと、コードは思ったように動作しなくなります。使用するtypeof方が優れており、宣言されていない変数(プロパティだけでなく)に対しても機能します。
Gabe Moothart、2010

7
何かが未定義のグローバル変数の場合、(something == undefined)はJavaScriptエラーを引き起こします。
モーガンチェン

8
これの問題は、aが最も確実に定義されていても、var a = nullの場合、a == undefinedがtrueと評価されることです。
Andrew

6
「Eloquent Javascript」コメントのこの解釈はです。本当に未定義をチェックしたいだけなら、提案されたコードは機能しません(定義された条件も検出しますが、値はまだ関連付けられていません[ienull])。null値。推奨されるコード「if(something == undefined)...」は、未定義とnull(値セットなし)の両方をチェックします。つまり、「if((something is undefined)OR(something is null))...」と解釈されます。著者が言っていることは、あなたが本当に望んでいることの多くは未定義とnullの両方をチェックすることです。
チャックコラーズ

125

これはどういう意味ですか:「未定義のオブジェクトプロパティ」

実際には、2つのまったく異なることを意味します。1 つ目は、オブジェクトで定義されたことのないプロパティを意味、2つ目は、値が未定義のプロパティを意味します。このコードを見てみましょう:

var o = { a: undefined }

されるo.a未定義?はい!その値は未定義です。されるo.b未定義?承知しました!プロパティ 'b'はありません!では、両方の状況で異なるアプローチがどのように動作するかを見てみましょう。

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

我々は明らかにそれを見ることができるtypeof obj.prop == 'undefined'obj.prop === undefined同等であり、それらは、それらの異なる状況を区別しません。また'prop' in obj、プロパティがまったく定義されておらず、定義されていない可能性のあるプロパティ値に注意を払っていない状況を検出できます。

じゃあ何をすればいいの?

1)プロパティが最初の意味でも2番目の意味でも定義されていないかどうかを知りたい(最も一般的な状況)。

obj.prop === undefined // IMHO, see "final fight" below

2)オブジェクトにプロパティがあり、その値を気にしないかどうかを知りたい場合。

'prop' in obj

ノート:

  • オブジェクトとそのプロパティを同時に確認することはできません。たとえば、xが定義されていない場合、this x.a === undefinedまたはthis typeof x.a == 'undefined'が発生しReferenceError: x is not definedます。
  • 変数undefinedはグローバル変数です(つまり、実際にはwindow.undefinedブラウザーにあります)。ECMAScript 1st Edition以降、ECMAScript 5以降は読み取り専用でサポートされています。したがって、最近のブラウザーでは、多くの作成者が私たちを怖がらせたいので、これをtrue再定義することはできませんが、これは古いブラウザーにも当てはまります。

ファイナルファイト:obj.prop === undefinedvstypeof obj.prop == 'undefined'

プラスobj.prop === undefined

  • それは少し短く、少しきれいに見えます
  • スペルミスがある場合、JavaScriptエンジンはエラーを表示します undefined

のマイナスobj.prop === undefined

  • undefined 古いブラウザで上書きできます

プラスtypeof obj.prop == 'undefined'

  • それは本当に普遍的です!新旧のブラウザで動作します。

のマイナスtypeof obj.prop == 'undefined'

  • 'undefned'スペルミス)ここは単なる文字列定数なので、JavaScriptエンジンは、私がしたようにスペルミスをした場合、あなたを助けることができません。

更新(サーバーサイドJavaScriptの場合):

Node.jsはグローバル変数undefinedをサポートしていますglobal.undefined(「グローバル」接頭辞なしでも使用できます)。サーバーサイドJavaScriptの他の実装については知りません。


@Bergiさん、コメントありがとうございます。私は私の答えを修正しました。私の弁護では、現在(v.0.10.18以降)の公式のNode.jsドキュメントundefinedのメンバーとして何も言及していないと言えglobalます。また、globalのメンバーとしてundefinedconsole.log(global);for (var key in global) { ... }表示れません。しかし、テストは反対を示しま​​す。'undefined' in global
コンスタンチンスモリャニン2013

4
EcmaScript仕様にあるため、追加のドキュメントは必要ありませんでした。これも[[Enumerable]]falseであると述べています:-)
Bergi

5
に関してはMinuses of typeof obj.prop == 'undefined'、これをと書くことで回避できますtypeof obj.prop == typeof undefined。これにより、非常に優れた対称性も得られます。
hlovdal 2014年

3
@hlovdal:それは完全に無意味obj.prop === undefinedです。
Ry-

1
最初の文の(異なる、はるかに簡単な)質問(「未定義かどうかを確認...」)に当てはまらない、質問の見出し„ 未定義のプロパティの検出に当てはまる場合、あなたは答えif ('foo' in oます...あなたの答えは本当にここで最初の正解。他のほとんどすべての人がその文に答えます。
Frank Nocke

70

問題は、3つのケースに要約されます。

  1. オブジェクトにはプロパティがあり、その値はではありませんundefined
  2. オブジェクトにはプロパティがあり、その値はundefinedです。
  3. オブジェクトにはプロパティがありません。

これは私が重要だと思うことを教えてくれます:

未定義のメンバーと、未定義の値を持つ定義済みメンバーとの間には違いがあります。

しかし、残念typeof obj.fooながら、3つのケースのどれが発生したかはわかりません。ただし、これを組み合わせ"foo" in objてケースを区別することができます。

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

これらのテストはnullエントリでも同じであることは注目に値します

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

プロパティが存在するかどうかを確認する方が、定義されていないかどうかを確認するよりも意味がある(そして明確である)場合があり、この確認が異なる唯一のケースはケース2で、まれなケースです。未定義の値を持つオブジェクトの実際のエントリ。

例:オブジェクトに特定のプロパティがあるかどうかをチェックする一連のコードをリファクタリングしています。

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

未定義のチェックなしで書かれたとき、それはより明確でした。

if( "x" in blob ) { fn(blob.x); }

しかし、すでに述べたように、これらはまったく同じではありません(ただし、私のニーズには十分満足できます)。


10
こんにちはマイケル。素晴らしい提案であり、それは物事をよりクリーンにすると思います。ただし、私が見つけた1つの問題は、!「in」を含む演算子。!はif (!("x" in blob)) {}括弧で囲む必要があります。演算子は「in」よりも優先されます。それが誰かを助けることを願っています。
サイモンイースト

Michaelさん、申し訳ありませんが、元の質問を踏まえると、これは正しくないか、少なくとも誤解を招く可能性があります。'in'は、オブジェクトプロパティのtypeofが未定義かどうかをテストするのに十分な方法ではありません。証明については、次のフィドルを参照してください:jsfiddle.net/CsLKJ/4
tex

2
これらの2つのコード部分は異なることをします!を考慮し、によって与えられたオブジェクトa = {b: undefined}。その後、typeof a.b === typeof a.c === 'undefined'しかし、'b' in a!('c' in a)
mgol 2012

3
+1。OPは、プロパティが存在し、値がundefinedであるかどうか、またはプロパティ自体が未定義(つまり、存在しない)であるかどうかを明確にしません。
RobG 2014

最初のテーブルのポイント(2.)を変更する{ x : undefined }か、少なくとも別の代替としてテーブルの(2.)に追加することをお勧めします。ポイント(2.)の評価がundefined(後で説明します)。
mucaho

46
if ( typeof( something ) == "undefined") 

これは私にとってはうまくいきましたが、他の人はうまくいきませんでした。


47
typeofは演算子なので、括弧は不要です
aehlke

12
しかし、彼らはチェックされているものをより明確にします。そうでない場合は、と読み取られる可能性がありますtypeof (something == "undefined")
Abhi Beckert 2012

:あなたが括弧を必要とする場合は、JSで演算子の優先順位を学ぶべきであるdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
イアン・

11
括弧は、JSでオペレーターの優先順位を学習する必要がなく、将来のメンテナンスプログラマーがJSでオペレーターの優先順位を学習する必要があるかどうかを推測する必要がないため、正確に役立ちます。
DaveWalley 2014

27
括弧は物事を明確にするのに役立ちます。ただし、この場合は、演算子を関数のように見せます。間違いなく、これはプログラマーの意図を明確にします。ただし、演​​算子の優先順位が不明な場合は、として記述してください(typeof something) === "undefined"
ロバート

42

===with の起源がどこtypeofから来たのかはわかりませんが、多くのライブラリで慣例として使用されていると思いますが、typeof演算子は文字列リテラルを返します。それもチェック?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

素晴らしいポイントエリック。タイプのチェックによるパフォーマンスへの影響はありますか?
Simon East

5
@Simon:まったく逆です。 '==='の場合、強制を回避することでパフォーマンスがわずかに低下することが予想されます。クイックアンドダーティーテストでは、「===」がFF5.0.1の「==」より5%速いことが示されています
Antony Hatchkins

5
より徹底的なテストでは、FF、IE、およびChromeで「==」が「===」よりも多少高速であり(5-10%)、Operaはまったく違いがないことを示しています。jsperf.com
アントニーハッチキンズ

3
==まだ使用するには、少なくとも型チェックが必要です-インタープリターは、最初に型を知らなければ2つのオペランドを比較できません。
Alnitak 2012

7
=====:) より1文字少ない
svidgen 2013年

25

私のクロスポストの答えを、関連する質問からどのようにJavaScriptで「未定義」をチェックするために?

この質問に固有のテストケースは、を参照してくださいsomeObject.<whatever>


さまざまな回答の結果を示すいくつかのシナリオ:http : //jsfiddle.net/drzaus/UVjM4/

varfor inテストを使用すると、スコープラッパー内で違いが生じることに注意してください)

参照用コード:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

そして結果:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined

21

もしあなたがそうするなら

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

myvarmyvarが定義されていないため、変数が存在しない場合は失敗します。そのため、スクリプトは壊れ、テストは効果がありません。

ウィンドウオブジェクトには関数の外部にグローバルスコープ(デフォルトオブジェクト)があるため、宣言はウィンドウオブジェクトに「アタッチ」されます。

例えば:

var myvar = 'test';

グローバル変数myvarwindow.myvarまたはwindow ['myvar']と同じです

グローバル変数が存在するときにテストするエラーを回避するには、以下を使用することをお勧めします。

if(window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

変数が実際に存在するかどうかは問題ではなく、その値は正しくありません。それ以外の場合、変数をundefinedで初期化するのはばかげています。値falseを使用して初期化することをお勧めします。宣言するすべての変数がfalseで初期化されていることがわかっている場合は、その型!window.myvarを確認するか、適切な値または有効な値があるかどうかを確認することができます。したがって、変数が定義されていない場合でも、or または!window.myvarは同じです。myvar = undefinedmyvar = falsemyvar = 0

特定の型が予想される場合は、変数の型をテストします。条件のテストをスピードアップするには、次のようにします。

if( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

最初の単純な条件が真の場合、インタープリターは次のテストをスキップします。

変数のインスタンス/オブジェクトを使用して、有効な値を取得したかどうかを確認することをお勧めします。それはより安定しており、プログラミングのより良い方法です。

(y)


19

プロパティの前にオブジェクトをチェックしている人を見かけませんでした(見逃してはいけません)。したがって、これは最も短く、最も効果的です(ただし、必ずしも最も明確ではありません)。

if (obj && obj.prop) {
  // Do something;
}

objまたはobj.propが未定義、null、または「偽」である場合、ifステートメントはコードブロックを実行しません。これは通常、ほとんどのコードブロックステートメント(JavaScript)で望ましい動作です。


2
あなたが知りたい場合は、なぜこの作品:Javascriptを:論理演算子とtruthy / falsy
MB21

あなたはそれが定義されていた場合、変数にNULLでないとないfalsey、他の利用いくつかのデフォルト値をプロパティを割り当てる場合は、使用することができます: var x = obj && obj.prop || 'default';
Stijn・デ・ウィット

問題は、未定義を明示的にチェックすることだと思います。JSのすべてのfalse値に対する条件チェック。
NikoKyriakid

15

記事「JavaScriptでNullと未定義の深淵を探索する」では、Underscore.jsのようなフレームワークがこの関数を使用することを読みました。

function isUndefined(obj){
    return obj === void 0;
}

3
void 0undefined(これはvoidの後に式が返すものなので)短い書き方なので、3文字節約できます。それも可能ですがvar a; return obj === a;、それはもう1つの文字です。:-)
RobG 2014

2
voidは予約語ですが、undefinedisではありません。つまり、デフォルトでundefinedはwhile が等しいためvoid 0undefinedたとえばに値を割り当てることができますundefined = 1234
ブライアンM.ハント

isUndefined(obj):16文字。 obj === void 0:14文字。十分に言った。
Stijn de Witt

14

単に何かがJavaScriptで定義されていない、未定義である、それがオブジェクト/配列内のプロパティであるか、単純な変数であるかは関係ありません...

JavaScriptではtypeof、未定義の変数を非常に簡単に検出できます。

単にかどうかtypeof whatever === 'undefined'を確認すると、ブール値が返されます。

これがisUndefined()、AngularJs v.1xの有名な関数の記述方法です。

function isUndefined(value) {return typeof value === 'undefined';} 

したがって、関数が値を受け取るのを見ると、その値が定義されている場合はが返されfalse、それ以外の場合は未定義の値が返されtrueます。

それでは、以下のようなオブジェクトプロパティを含む、値を渡したときの結果を見てみましょう。これは、変数のリストです。

var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;

以下のようにチェックします。コメントの前に結果が表示されます。

isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true

ご覧のとおり、コードでこのようなものを使用して何でもチェックできます。前述のようtypeofに、コードで単純に使用できますが、何度も使用している場合は、角度サンプルのような関数を作成し、共有して再利用します。次のDRYコードパターン。

また、実際のアプリケーションでオブジェクトが存在するかどうかさえわからないオブジェクトのプロパティを確認するには、オブジェクトが最初に存在するかどうかを確認します。

オブジェクトのプロパティをチェックしてもオブジェクトが存在しない場合は、エラーをスローし、アプリケーション全体の実行を停止します。

isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)

とても簡単なので、以下のようにifステートメント内でラップできます。

if(typeof x !== 'undefined') {
  //do something
}

これは、Angular 1.xのisDefinedとも同じです...

function isDefined(value) {return typeof value !== 'undefined';}

また、アンダースコアのような他のJavaScriptフレームワークにも同様の定義チェックがありますがtypeof、フレームワークをまだ使用していない場合は使用することをお勧めします。

また、typeof、undefined、およびvoid(0)に関する有用な情報を得たMDNからこのセクションを追加します。

厳密な等価および未定義
変数に値があるかどうかを判別するには、未定義演算子と厳密な等価演算子および不等式演算子を使用できます。次のコードでは、変数xは定義されておらず、ifステートメントはtrueと評価されます。

var x;
if (x === undefined) {
   // these statements execute
}
else {
   // these statements do not execute
}

注:ここでは、x == undefinedもxがnullかどうかをチェックしますが、厳密な等価演算子はnullでないため、標準の等価演算子ではなく厳密な等価演算子を使用する必要があります。nullはundefinedと同等ではありません。詳細については、比較演算子を参照してください。


Typeof演算子と未定義
別の方法として、typeofを使用することもできます。

var x;
if (typeof x === 'undefined') {
   // these statements execute
}

typeofを使用する1つの理由は、変数が宣言されていなくてもエラーをスローしないためです。

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
   // these statements execute
}

if (x === undefined) { // throws a ReferenceError

}

ただし、このような手法は避けてください。JavaScriptは静的スコープ言語であるため、変数が宣言されているかどうかは、それが囲みコンテキストで宣言されているかどうかを確認することで読み取ることができます。唯一の例外はグローバルスコープですが、グローバルスコープはグローバルオブジェクトにバインドされているため、グローバルコンテキスト内の変数の存在を確認するには、グローバルオブジェクトのプロパティの存在を確認します(in演算子を使用して、例えば)。


void演算子と未定義

void演算子は3番目の選択肢です。

var x;
if (x === void 0) {
   // these statements execute
}

// y has not been declared before
if (y === void 0) {
   // throws a ReferenceError (in contrast to `typeof`)
}

もっと> ここに


13

' if(window.x){} 'はエラーセーフです

ほとんどの場合、あなたが欲しいif (window.x)。このチェックは、xが宣言されていなくても安全です(var x;)-ブラウザはエラーをスローしません。

例:ブラウザがHistory APIをサポートしているかどうかを知りたい

if (window.history) {
    history.call_some_function();
}

仕組み:

windowは、すべてのグローバル変数をメンバーとして保持するオブジェクトであり、存在しないメンバーにアクセスしようとすることは合法です。場合xが宣言されていないか、そして、設定されていないwindow.xリターンは未定義undefinedは、if()が評価しときにfalseになります。


しかし、Nodeで実行するとどうなるでしょうか。typeof history != 'undefined'実際には両方のシステムで動作します。
Stijn de Witt 2015

13

これを読んで、私はこれを見ていないことに驚いています。私はこれのために働くだろう複数のアルゴリズムを見つけました。

定義されていない

オブジェクトの値trueが定義されたことがない場合、nullまたはとして定義されていると、戻り値が返されなくなりundefinedます。これは、次のように設定された値に対してtrueを返す場合に役立ちます。undefined

if(obj.prop === void 0) console.log("The value has never been defined");

未定義または未定義として定義

true値で定義された値のように結果が欲しい場合undefined、または定義されていない場合は、単純に=== undefined

if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");

偽の値として定義されている、未定義、null、または定義されていない。

一般的に、人々は、値がどちらかfalsyであれば把握するアルゴリズムのための私を求めているundefined、またはnull。以下の作品。

if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
    console.log("The value is falsy, null, or undefined");
}

4
最後の例を次のように置き換えることができると思いますif (!obj.prop)
Stijn de Witt

@StijndeWitt、できます。私がこれを書いたとき、私はかなり経験が浅かったのですが、私の英語は同様に悪いようでした、それにもかかわらず、答えに誤りはありません
Travis

3
var obj = {foo: undefined}; obj.foo === void 0-> true。これは「決して」と定義されていませんundefinedか?これは間違っています。
Patrick Roberts

@PatrickRobertsそうですね。2015年2月(ES6より前)にこの回答を書いたとき、最初に説明したオプションは確かに機能しましたが、現在は古くなっています。
トラビス


10

void 0簡潔さについては、と比較してください。

if (foo !== void 0)

それは冗長ではありません if (typeof foo !== 'undefined')


3
しかし、fooが宣言されていない場合はReferenceErrorをスローします。
daniel1426 2014年

1
@ daniel1426:コードにエラーがある場合、修正するのではなく非表示にしたいですか?素晴らしいアプローチではありません、IMO。

これは、エラーを非表示にするためには使用されません。これは、環境のプロパティを検出してポリフィルを定義する一般的な方法です。例:if(typeof Promise === 'undefined'){/ * define Promise * /}
ギャパートン

10

ソリューションは正しくありません。JavaScriptでは、

null == undefined

どちらもブール値に「キャスト」され、falseであるため、trueを返します。正しい方法はチェックすることです

if (something === undefined)

これは恒等演算子です...


3
明確にするために、===タイプの等価性+(プリミティブの等価性|オブジェクトID)であり、プリミティブには文字列が含まれます。アイデンティティオペレーターとして考えると、ほとんどの人は'abab'.slice(0,2) === 'abab'.slice(2)直感的ではないと考え===ています。
10

1
違う。変数が作成されていない場合、エラーがスローされます。投票しないでください。代わりにtypeofを使用してください。
Simon East

10

次のコードを使用して、パスですべて未定義の配列を取得できます。

 function getAllUndefined(object) {

        function convertPath(arr, key) {
            var path = "";
            for (var i = 1; i < arr.length; i++) {

                path += arr[i] + "->";
            }
            path += key;
            return path;
        }


        var stack = [];
        var saveUndefined= [];
        function getUndefiend(obj, key) {

            var t = typeof obj;
            switch (t) {
                case "object":
                    if (t === null) {
                        return false;
                    }
                    break;
                case "string":
                case "number":
                case "boolean":
                case "null":
                    return false;
                default:
                    return true;
            }
            stack.push(key);
            for (k in obj) {
                if (obj.hasOwnProperty(k)) {
                    v = getUndefiend(obj[k], k);
                    if (v) {
                        saveUndefined.push(convertPath(stack, k));
                    }
                }
            }
            stack.pop();

        }

        getUndefiend({
            "": object
        }, "");
        return saveUndefined;
    }

jsFiddleリンク


コードの有効性には影響しませんが、タイプミスgetUndefiendがありますgetUndefined
icktoofay 2013年

8

これが私の状況です:

REST呼び出しの結果を使用しています。結果はJSONからJavaScriptオブジェクトに解析されます。

私が守る必要のあるエラーが1つあります。引数を間違って指定している限り、残りの呼び出しに対する引数が正しくなかった場合、残りの呼び出しは基本的に空に戻ります。

この投稿を使用してこれを防ぐ手助けをしている間に、私はこれを試しました。

if( typeof restResult.data[0] === "undefined" ) { throw  "Some error"; }

私の状況では、restResult.data [0] === "object"であれば、残りのメンバーの検査を安全に開始できます。未定義の場合は、上記のエラーをスローします。

私が言っているのは、私の状況では、この投稿の上記の提案はすべて機能しなかったということです。私が正しいと言っているのではなく、誰もが間違っています。私はJavaScriptのマスターではありませんが、これが誰かの役に立つことを願っています。


あなたのtypeofガードは、直接比較が処理できなかったものに対して実際にはガードしません。restResultが未定義または未宣言の場合でも、スローされます。

あなたのケースでは、配列が空であるかどうかをより簡単にチェックできます:if(!restResult.data.length) { throw "Some error"; }
Headbank

8

定義済みのプロパティが定義されている場合は、新しい変数に割り当てたり、未定義の場合はフォールバックとしてデフォルト値を割り当てたりするには、洗練された方法があります。

var a = obj.prop || defaultValue;

追加の構成プロパティを受け取る関数がある場合に適しています。

var yourFunction = function(config){

   this.config = config || {};
   this.yourConfigValue = config.yourConfigValue || 1;
   console.log(this.yourConfigValue);

}

現在実行中

yourFunction({yourConfigValue:2});
//=> 2

yourFunction();
//=> 1

yourFunction({otherProperty:5});
//=> 1

7

すべての答えは不完全です。これは、「未定義として定義された」プロパティがあることを知る正しい方法です。

var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
  return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;

例:

var a = { b : 1, e : null } ;
a.c = a.d ;

hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null

// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined

これが正解であることは残念ですが、間違った答えに埋もれています> _ <

だから、通り過ぎる人のために、私はあなたに無料で未定義を与えます!

var undefined ; undefined ; // undefined
({}).a ;                    // undefined
[].a ;                      // undefined
''.a ;                      // undefined
(function(){}()) ;          // undefined
void(0) ;                   // undefined
eval() ;                    // undefined
1..a ;                      // undefined
/a/.a ;                     // undefined
(true).a ;                  // undefined

7

コメントを確認すると、両方を確認したい人のために、コメントが未定義であるか、その値がnullであるかを確認します。

//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
    alert('either it is undefined or value is null')
}

jQuery Libraryを使用jQuery.isEmptyObject()している場合は、どちらの場合も十分です。

var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;

s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;

//Usage
if (jQuery.isEmptyObject(s)) {
    alert('Either variable:s is undefined or its value is null');
} else {
     alert('variable:s has value ' + s);
}

s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;

jQueryは、さまざまなJavaScript APIとのブラウザー間の互換性の問題にも対応します。
Henry Heleine 2014

7

Angularを使用している場合:

angular.isUndefined(obj)
angular.isUndefined(obj.prop)

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 

2
1変数に追加するにはどうすればよいxですか?UnderscoreまたはjQueryが必要ですか?(人々がtypeof小切手などの最も基本的な操作でさえライブラリーを使用することに驚く)
Stijn de Witt

6

if (this.variable)それが定義されているかどうかをテストするために使用します。if (variable)推奨されている Simple は私にとって失敗します。これは、変数が何らかのオブジェクトのフィールドである場合にのみ機能obj.someFieldし、辞書で定義されているかどうかを確認します。しかし、私が理解しているように、変数は現在のウィンドウのフィールドであるため、thisまたはwindowを辞書オブジェクトとして使用できます。したがって、ここにテストがあります

if (this.abc) alert("defined"); else alert("undefined");

abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");

最初に変数abcが未定義であり、初期化後に定義されていることを検出します。


5

奇妙な答えを期待する人のために、ここで3つの方法を提供します。

function isUndefined1(val) {
    try {
        val.a;
    } catch (e) {
        return /undefined/.test(e.message);
    }
    return false;
}
function isUndefined2(val) {
    return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
    const defaultVal={};
    return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
    console.group(`test start :`+func.name);
    console.log(func(undefined));
    console.log(func(null));
    console.log(func(1));
    console.log(func("1"));
    console.log(func(0));
    console.log(func({}));
    console.log(func(function () { }));
    console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);

isUndefined1:

入力値のプロパティを取得してみてください。存在する場合はエラーメッセージを確認してください。入力値が未定義の場合、エラーメッセージはUncaught TypeError:Undefinedプロパティ 'b'を読み取れません

isUndefined2:

入力値を文字列に変換して比較し"undefined"、負の値であることを確認します。

isUndefined3:

jsでは、オプションのパラメーターは、入力値が正確にのときに機能しますundefined


5

ES2019は新機能を導入しました- オプションの連鎖を使用して、オブジェクトが次のように定義されている場合にのみオブジェクトのプロパティを使用できます。

const userPhone = user?.contactDetails?.phone;

userおよびcontactDetailsが定義されている場合にのみ、phoneプロパティを参照します。

参照 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining


以前はlodashから取得する関数をたくさん使用していましたが、この種のオブジェクトにアクセスするには非常に便利ですが、新しいオプションのチェーンは_.getのほとんどの用途をカバーしています
Al Hill

4
function isUnset(inp) {
  return (typeof inp === 'undefined')
}

変数が設定されている場合はfalseを返し、未定義の場合はtrueを返します。

次に使用します:

if (isUnset(var)) {
  // initialize variable here
}

5
いいえ、これを行わないでください。テストtypeof関数内に有意義にラップできないことを証明するは、非常に単純なテストのみが必要です。4人がこれに賛成したことは驚くべきことです。-1。
Stijn de Witt

4

undefined変数を保護するために使用しているものを紹介します。

Object.defineProperty(window, 'undefined', {});

これは誰もがwindow.undefined値を変更することを禁止し、そのためその変数に基づくコードを破壊します。を使用している場合"use strict"、その値を変更しようとするとエラーで終了します。それ以外の場合は、黙って無視されます。


4

プロキシを使用することもできます。これはネストされた呼び出しで動作しますが、追加のチェックが1つ必要になります。

function resolveUnknownProps(obj, resolveKey) {
  const handler = {
    get(target, key) {
      if (
        target[key] !== null &&
        typeof target[key] === 'object'
      ) {
        return resolveUnknownProps(target[key], resolveKey);
      } else if (!target[key]) {
        return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
      }

      return target[key];
    },
  };

  return new Proxy(obj, handler);
}

const user = {}

console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

したがって、次のように使用します。

const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
  // do someting
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.