• ベストアンサー

JavaScriptのnullはいつ使う?

JavaScriptにはnullという値がありますが、いつ使うのでしょうか。 値が定義されていない変数やプロパティには、undefinedが入っていますし、 undefinedを代入することもできます。 C#でのnullの使い方と同じように、undefinedが使えちゃってます。 ではnullはいつ使うのでしょう? undefinedではなくnullでなければダメなケースって何がありますか?

  • mokpok
  • お礼率62% (154/245)

質問者が選んだベストアンサー

  • ベストアンサー
  • think49
  • ベストアンサー率59% (285/482)
回答No.1

C# は知らないのでどう伝えるべきか迷いますが…、簡単に説明すると次のようになります。 ・undefined … 未定義 ・null … 値が存在するが falsy な値 JavaScript は型付けの緩い言語といわれますが、ある変数を定義したときその変数に格納される型を統一するのが一般的です。 --- var number = 1; // Number型の値を代入 number = -1; // 不要になったので falsy な値を入れる (ex: 0, -1, NaN等) --- では、Object型はどうなるでしょうか。 ネイティブ実装されている関数は返り値の型に統一性があります。 Number型を返す関数なら必ずNumber型を返しますが、Object型を返す関数には二通りがあります。 --- var p = document.getElementsByTagName('p'); // p要素が全くなければ空のNodeListを返す var string = 'Hello, World!'; console.log(string.match(/Hello/i)); // ["Hello"] console.log(string.match(/Hoge/i)); // null (マッチしなければ null を返す) --- このように null はObject型とセットで使われる場合があります。 空のオブジェクトはBoolean型に変換すれば true になりますが、null は false に変換されます。 --- if ({}) {  console.log('{} は true に変換される'); } if (null) {  console.log('null は false に変換される'); } --- undefined は未定義を表しますが、null は値を返した上で false であると明示している違いがあります。 あるプロパティに undefined を定義すれば、コードの書き方によっては「そのプロパティがない」と判断されてしまうかもしれません。 --- function hasProperty1 (object, property) { return typeof object.property !== 'undefined'; } function hasProperty2 (object, property) { return property in object; } var object = {hoge: 'Hello', foo: undefined}; console.log(hasProperty1(object, 'foo')); false console.log(hasProperty1(object, 'piyo')); false console.log(hasProperty2(object, 'foo')); true console.log(hasProperty2(object, 'piyo')); false --- hasProperty1 の書き方は間違いですが、undefined にはプロパティ未定義と同じ値を返す意味があることは覚えておく必要があります。

mokpok
質問者

お礼

ありがとうございます。 機能上の違いというよりは、意味の違いの重視で可読性を上げるという観点ですね。

その他の回答 (7)

  • Chaire
  • ベストアンサー率60% (79/130)
回答No.8

恥ずかしながら、No.5 修正。 > function abort(message):Void → function abort(message):Never > function display(message):Void { // この関数は処理を返さない → function display(message):Void { // この関数の戻り値は無効 --- なお、私は No.6 の taloo さんの使い方に概ね賛成です。JavaScript の「ユルさ」は、存在しないプロパティにアクセスしてもエラーにならず、undefined という「値」が返ってくることにあります。 しかしながら、存在しないプロパティにアクセスしたとき、なぜ undefined ではなく null を返すのではいけないのか? それは、分かりません。必ずしも駄目というわけでなく、歴史的な話のような気がします。 ※詳しくは割愛しますが、JavaScript における null と undefined および型変換の扱いは最初期から混乱を極めています。JS 1.2 で整合性を図ろうとするも失敗し、JS 1.3 で厳密等価演算子 === とグローバル変数 undefined を導入することで、何とか今の状態まで持ち直しました。さらに MacIE との互換性まで含めると、本当に大変だったのです。 また、No.7 で指摘されているように、オブジェクト階層として null と undefined をどこに位置づけるかも問題になります。少なくとも、null をオブジェクトに含めるのは(No.5 に挙げたリンク先にも書かれているように)0 == 1 と見なすことになりますので、論理の根底を覆す大問題です。幸い、今でも null instanceof Object の方なら false になりますけどね。 さらにさらに、undefined は必ずしも「プロパティが存在しない」ことを意味しません。JavaScript では「プロパティが存在しない」と、「プロパティは存在するが値が undefined である」の 2 つの状態がありえますが、undefined だけではこれらを区別できません。だから、prop in obj のように屋上屋を架すような拡張がなされ、これがまた No.2 で触れられているようなラッパーとの衝突を生んだわけで。 次世代 ES では、この辺の意味論をすっぱり整理してほしい所ですけどねえ。No.5 で、実用化されていない型推論を引き合いに出したのはそのためです。

mokpok
質問者

お礼

ありがとうございます。 そういえばundefinedがグローバル変数であることも、 途中で仕様追加されたという経緯がありましたね・・・ 確かにすっぱり整理してほしいです。 であればこんな質問も必要無かったんですが・・・

  • think49
  • ベストアンサー率59% (285/482)
回答No.7

To: #6 (taloo) さん typeof null === 'object' は仕様バグとされています。 http://web.archive.org/web/20071110193102/http://bugs.ecmascript.org/ticket/250 http://d.hatena.ne.jp/think49/20120114/1326554107 次期ECMAScriptである ES.next では typeof null === 'null' に修正される予定です。 http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null

回答No.6

文法、言語仕様による定義はちょっとわかりませんが、 私の考え、使い方は、 null:「明示的」な何も指定しないことの指定 undifined:「暗黙的」な何も指定しないことの指定 引数や代入には何も指定しないことを明示するわけですから、必然的に「暗黙」を使うことはなくなります。 function f(arg){ if(arg===undefined){ // デフォルト処理 } } f(); f(null); f(undefined); //この使い方はしない 質問には関係ないと思いますが、nullはnullオブジェクトです。 alert( typeof(null) ); // 'object' alert( typeof(undefined) ); // 'undefined' JavaScriptでは、null、undefined、false、0、''(空文字列)がBooleanに型変換(キャスト)したときにfalseになり、 それ以外はすべてtrueになります。 a=null; if( a ) {} b=0; if( b ) {}

mokpok
質問者

お礼

ありがとうございます。 やはり機能上の違いではなく、意味分けして使うケースの方が多そうですね。

  • Chaire
  • ベストアンサー率60% (79/130)
回答No.5

「値がない」ことについて、今は亡き JavaScript 2.0(ECMAScript 4)には、Never 型、Void 型、Null 型の 3 つがありました。 Never は「値がない」本当の空集合です。処理を返しません。 function abort(message):Void {  throw AbortException(message);  // この関数は処理を返さない } Void は「値が無効」を示す undefined を一つだけ含む集合です。戻り値を無視して処理続行されます。 function display(message):Void {  print(message);  // この関数は処理を返さない } Null は「値がないかもしれない」を示す null を一つだけ含む集合です。値が null であるかがチェックされます。 function getHoge(obj):Object {  if (...) return obj.hoge; else return null; } これらは、本当はコンパイラの型検証に使われるものです(でした)。実際に動かすまでもなく、コンパイル時点で「ありえない値」が来そうな部分はエラーないし警告を出す、ということです。 型検証のない現在の JS エンジンではあまり恩恵がないかもしれません。しかし、JS での動的な型検証の試みは多いので、将来的には何らかのツールが出るかもしれません。 --- E4X(ECMAScript for XML)では、次のように null と undefined を使い分けています。 ・Namespace.prefix が空文字列ならデフォルト名前空間、undefined なら未宣言の接頭辞。 ・QName.uri が空文字列なら名前空間なし、null なら任意の名前空間。 つまり、XML 文書で宣言されていない(後で XML 文書に書き出すときに特別処理が必要)な接頭辞に、とりあえず undefined を入れておきます。また、「任意の」を示すときに null を入れておきます。 そういう使い分けもある、という事例の一つとして。 ※ DOM において null が多用されるのは IDL の制約によるもので、それ自体に意味はそんなにありません。 参考: http://d.hatena.ne.jp/m-hiyama/20060314/1142304375 http://d.hatena.ne.jp/m-hiyama/20110704/1309737089

  • BellBell
  • ベストアンサー率54% (327/598)
回答No.4

>C#でのnullの使い方と同じように、undefinedが使えちゃってます。 使えるという事と、使うという事の違いですかね…。 undefinedは#1の方の言う通り未定義ですが、あえて意訳で未初期化と訳したいですね。 C言語やC++では(C#に非ず)、未初期化な変数は何が入っているか判らない変数です。 初期化せずに使うと、何が起こるか判らないパルプンテな状態です。 JavaScriptの仕様の制定者はそんなパルプンテ状態を嫌って、未定義で初期化する事を選んだんじゃないかという気がします(だから意訳としても未初期化と訳すのは完全に間違い)。 Cの流儀では未初期化な変数を使うのは恥ずかしい。 その流儀をJavaScriptに輸入すると、宣言時にvar hoge = null;と初期化してやればいいだけ。 ※Cでは未宣言の変数は使えないので、宣言するというのもCの流儀の輸入 そもそも、undefinedを使う機会自体が存在しないってな感じなんですけどね。 ま、それはJavaScriptの流儀ではない、それはあくまでCの流儀だと言われてしまえばそれまでなんですが。 未定義を代入ってのは意味論的に見ると違うんじゃないかな、って気持ちがあるんですよね。 その気持ちを加味すると、意訳で未初期化と訳してしまいたくなります。 これも、個人の感覚を持ち込むなって言われてしまうとそれまでなんですが。 解答ではなく個人的意見の表明になってしまいましたが、そんな考え方もあるという事で。

mokpok
質問者

お礼

確かにundefinedの意味を考えるとundefined代入は気持ち悪いですね。 実際に代入するケースはあまり無い気もしますが・・・

  • think49
  • ベストアンサー率59% (285/482)
回答No.3

#1,2 です。 某所で指摘を受けまして、「-1 は falsy ではない」ことに気がつきました。 Number型で falsy な値は「0, NaN」なので、#1 の冒頭は次のように訂正します。 --- var number = 1; // Number型の値を代入 number = 0; // 不要になったので falsy な値(0 or NaN)を入れる --- 失礼しました。

  • think49
  • ベストアンサー率59% (285/482)
回答No.2

#1 です。 null でなければ駄目なケースとしてはイベントハンドラの削除があります。 http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#events --- function handleClick () { alert('onclick'); } function sample () {  element.onclick = handleClick; // element にonclickハンドラを定義する  element.onclick = null; // elementのonclickハンドラを削除する } ---- 個人的には、null か undefined かはコードリーディングする上でわかりやすいかという側面が強いと思います。 その観点では「nullでなければ駄目なケース」より「undefined でなければ駄目なケース」の方が少ないですね。 少なくとも私は「不要になったら null で埋める」という使い方はあっても、undefined で埋めることはしたことがありません。 # jquery-1.7.1.js で見られる undefined の使い方も気持ち悪く感じます…。 話変わりますが、'onclick' in window === false な実装をしていた Firefox 4 の不具合は Firefox 9 では修正されているようです。 http://togetter.com/li/171744 この辺も undefined の扱いに違いが見られるところですね。

mokpok
質問者

お礼

ありがとうございます。 そういえば確かに、イベントハンドラはnull代入のみでした。 それともう一点、document.getElementByIdも見つからないとnullを返しました。

関連するQ&A

  • undefinedかnullかどう区別できますか?

    JavaScript の教科書に下記のように記載があったのですが、 >>> ページからアンカータグを取得するgetAnchorという関数があったとします。 その際、アンカータグが見つからなかったならば、何を返すべきでしょうか。undefined(未定義)は不自然です。 今度は「該当する値がなかった(=空であった)」という値を、意図して伝えようとしているので、nullを返すべきです。 関数で値が返されなかった場合はundefinedと聞いたのですが上記はそれに該当するように私は思ってしまうのですが、なぜ違うかわかりますか? 関数で値が返されなかった場合とはalert()のように引数がなかった場合という意味でしょうか? それともretunr 変数名などのreturnがない場合という意味でしょうか?

  • JavaScriptからJavaScriptを呼ぶ方法?

    あるJavaScriptのファイルでで変数に値を代入します。 他の複数のJavaScriptのファイルで、その変数を使用したいと思います。 JavaScript{     JavaScript{     }     処理・・・・ } という形になるのでしょうか。 このように、他のJavaScriptから変数を呼び出したいのです。 どのように記述したら良いでしょうか?

  • 変数にnullを代入するには

    諸事情で、変数の値をNullにしたいのですが、 Sub a() Dim mystr As String mystr = "moji" '他の処理 mystr = Null End Sub だと、実行時エラー94になります。 多分、NULLは値じゃないから代入できないんだと思いますが、どうすれば変数をnullにできるのでしょうか? String型が問題であれば、何にすればいいですか?

  • 変数の未定義の判定(JavaScript)

    JavaScriptである名前の変数の定義済み、未定義の判定をする際に 以下のようにするとエラーになりますが、何か方法がないでしょうか。 if (myval == "undefined") {  alert("未定義"); }

  • javascriptの値をPHPへ渡したい

    javascriptの値をPHPへ渡したい javascriptで計算された値をphpの変数へ代入し、その後の PHPで利用したいと考えています。 どのように代入すればよいでしょうか。。。 そもそもそのような事が可能なのでしょうか。。。 初歩的な事で申し訳ありませんが、教えて下さい。

    • ベストアンサー
    • PHP
  • NULL値をゼロとして扱うには?

    JavaScriptでNULL値をゼロとして扱いたいのですが、"parseFloat"や"eval"などで変換してもはゼロ数値として扱ってくれません。やはり、"NaN"や"Undefined"かどうか判断して、そうであった場合は"0"に変換するというステップが必要なのでしょうか? なんかスムーズじゃなくて納得できません。

  • null代入とunset()の違いについて

    null代入とunset()では、違いがあるのでしょうか? 検索してみたところ、下記ページにたどり着いたのですが、 結論としては、このページ下のコメントに書かれているとおり、 あまり気にしなくてよいでしょうか? ▽http://www.cpa-lab.com/tech/097 >利用者からは気にする必要が無い部分ではないかと <経緯> nullが分からないので、調べていました。 var_dump($x);//未定義では、NULL $x = NULL; var_dump($x);//NULLを代入しても、NULL $y = "hoge"; unset($y); var_dump($y);//unsetしても、NULL ここまできて、 「NULLを代入する」と、「変数破棄」の違いが、 分からなくなりました…

    • ベストアンサー
    • PHP
  • obj.property のundefined判定

    obj.property のundefined判定 未定義のローカル変数を評価すると、以下の結果になります。 <script type="text/javascript"><!-- var a; if(a === undefined){ alert('a is undefined!'); } // エラーは発生しない if(b === undefined){ alert('b is undefined!'); } // 「ReferenceError: b is not defined」のエラーが発生し、if文が評価されない if('undefined' === typeof b){ alert('b is undefined!'); } // エラーは発生しない //--></script> 未定義のローカル変数は undefined との比較ではチェックできず、typeof でチェックする必要があることが分かります。 対して、「存在が保証されているオブジェクトの存在しないプロパティ」でチェックすると、以下の結果になります。 <script type="text/javascript"><!-- var obj = { a:'valueA', b:'valueB' }; if(obj.property === undefined){ alert('obj.property is undefined!'); } // エラーは発生しない if('undefined' === typeof obj.property){ alert('obj.property is undefined!'); } // エラーは発生しない //--></script> 不思議に思い、ECMA-262 3rd Edition仕様書を読んでみたところ、下記文言が見つかりました。 ---------- 8.6.2.1 [[Get]] (P) O の [[Get]] メソッドがプロパティ名 P で呼出されると、次のステップがとられる: 1. O が P という名前のプロパティを持っていなければ、ステップ 4 へ進む。 2. そのプロパティの値を取得する。 3. Result(2) を返す。 4. O の [[Prototype]] が null ならば、undefined を返す。 5. [[Prototype]] の [[Get]] メソッドを、プロパティ名 P で呼び出す。 6. Result(5) を返す。 http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/8_Types.html#section-8.6.2 ---------- この場合、ステップ4の「obj.property が nullなため undefined を返す」という処理が行われた、という解釈で合っているでしょうか? ほぼ正しいと感じているのですが、「仕様書の中で見るべきところが合っているのか」に自信が持てず、確信に至っていません…。

  • NULL

    C言語で、0の代入とNULLの代入はバイナリレベルでは同じ事だと聞いたのですが本当なんでしょうか? とすると int i = 0; と int i= NULL; は、同じ事なんでしょうか。 また、 if(!aaaa){ と if(aaaa == NULL){ は同じ条件文なんでしょうか?

  • JavaScriptで特定の変数に値が代入されるのを禁止する。

    JavaScriptで、既存の変数に値を代入し、その後の上書き(その変数への値の代入)を禁止するにはどのようにすればよいでしょうか。 <script type="text/javascript"><!-- var hoge = "hogeは初期化されてます"; hoge = "hogeは変更されました";//ここ以降での変更(代入)を禁止したい。 hoge = "hoge変更2回目"; alert(hoge); //--></script> というスクリプトを書いたときに、alert(hoge)で「hogeは変更されました」と表示させたいのです。 他の方法は駄目です。この方法だけでお願いします。 よろしくお願いします。

専門家に質問してみよう