web-dev-qa-db-ja.com

JavaScriptに「null」値があるのはなぜですか?

JavaScriptには、基本的に「存在しない」という2つの値があります-undefinednullです。

プログラマが何も割り当てていないプロパティはundefinedになりますが、プロパティがnullになるには、nullを明示的に割り当てる必要があります。

nullはプリミティブな値であり、undefinedはオブジェクトであるため、nullが必要だと思ったことがあります。それはそうではありません、たとえtypeof null'object'を生成したとしても:実際には、両方ともプリミティブ値です-つまり、コンストラクター関数からundefinednullも返せないことを意味します。コンストラクター内)。

また、両方ともブールコンテキストでfalseに評価されます。私が考えることができる唯一の本当の違いは、数値コンテキストで1つがNaNに評価され、もう1つが0に評価されることです。

では、プロパティが設定されているかどうかを調べるときにundefinedを誤ってチェックしているプログラマを混乱させるだけで、nullnullの両方があるのはなぜですか?

私が知りたいのは、誰かがnullを使用する必要がある合理的な例を持っているかどうかであり、undefinedを使用して表現することはできませんでした。

したがって、一般的なコンセンサスは、undefinedは「そのようなプロパティはありません」を意味し、nullは「プロパティは存在するが値を持たない」ことを意味するようです。

JavaScript実装が実際にこの動作を強制する場合、私はそれに耐えることができますが、undefinedは完全に有効なプリミティブ値であるため、既存のプロパティに簡単に割り当ててこの契約を破ることができます。したがって、プロパティが存在するかどうかを確認する場合は、とにかくin演算子またはhasOwnProperty()を使用する必要があります。もう一度:undefinednullの個別の値の実際の使用法は何ですか?

使用されなくなったが、undefinedにはしたくないプロパティの値を設定解除する場合は、実際にdeleteを使用します。代わりにnullを使用する必要がありますか?

111
Christoph

問題は、実際には「JSにnull値がある理由」ではありません-ほとんどの言語にある種のnull値があり、一般に非常に有用であると考えられています。

問題は、「JSに未定義値がある理由」です。使用される主な場所:

  1. 「var x;」を宣言するときただし、割り当てないでください。xは未定義です。
  2. 関数が宣言するよりも引数の数が少ない場合。
  3. 存在しないオブジェクトプロパティにアクセスするとき。

'null'は(1)と(2)*に対しても同様に機能していました。 (3)実際にすぐに例外をスローする必要があり、そうではなく、後で失敗するこの奇妙な「未定義」を返すという事実は、デバッグの難しさの大きな原因です。

*:(2)は例外をスローするべきであると主張することもできますが、その場合は、デフォルト/変数の引数に対して、より優れた、より明示的なメカニズムを提供する必要があります。

ただし、JavaScriptには元々例外も、特定の名前のメンバーがいるかどうかをオブジェクトに尋ねる方法もありませんでした-唯一の方法は、メンバーにアクセスし、何を取得するかを確認することでした。 「null」にはすでに目的があり、メンバーをそれに設定したい場合があるため、別の帯域外の値が必要でした。したがって、「未定義」があり、指摘するように問題があります。これは、決して取り除くことができないもう1つの優れたJavaScriptの「機能」です。

使用されなくなったが削除したくないプロパティの値を設定解除する場合は、実際にはundefinedを使用します。代わりにnullを使用する必要がありますか?

はい。代わりに他の言語が例外をスローする可能性がある場合、シグナリングの特別な値として「未定義」を保持します。

「null」に設定するとエラーが発生する可能性のある一部のIE DOMインターフェースを除き、通常は 'null'の方が適しています。この場合、空の文字列への設定が機能する傾向があります。

72
bobince

こちら が最もよく説明されていますが、要約すると:

undefinedはタイプと値の欠如であり、nullは値の欠如です。

さらに、単純な「==」比較を行う場合、あなたは正しい、それらは同じになります。ただし、タイプと値の両方を比較する===を試してみてください。違いに気付くでしょう。

37
Eddie Parker

nullundefinedの両方を持つ理由はないと思います。なぜなら、多くの人が示唆している唯一の理由だからです(「undefinedはそのような変数/プロパティがないことを意味します」)少なくともJavaScriptでは無効です。 undefinedは、変数/プロパティが存在するかどうかを判断できません。

console.log(foo);               // "ReferenceError: foo is not defined"
                                // foo does not exist
var foo;
console.log(foo);               // "undefined", a different response
console.log(foo === undefined); // "true", but it does exist

var obj = {};
console.log(obj.hasOwnProperty("foo")); // "false", no such property
obj.foo = undefined;
console.log(obj.hasOwnProperty("foo")); // "true", it exists and has the value "undefined"
console.log(obj.foo === undefined);     // "true", but it does exist

obj.bar = "delete me";
obj.bar = undefined;
console.log(obj.hasOwnProperty("bar")); // "true", not actually deleted
delete obj.bar;
console.log(obj.hasOwnProperty("bar")); // "false", deleted

ご覧のように、foo === undefinedは、fooが存在するかどうか、およびobj.bar = undefinedは実際にはbarを削除しません。

undefinedが「存在しない」ことを表すべきであるというのは、JavaScript作成者の本来の意図かもしれません。しかし、実装はそのようにはなりませんでした。

16
Lei Zhao

両方が必要になることは完全に可能です。たとえば、WMIをクエリする場合、クラスがnull値を持つプロパティを返すようにすることは完全に可能です。それらは定義されており、たまたまヌルを保持しているだけです。

6
EBGreen

JavaScriptがundefinedを「そのようなプロパティはない」と定義し、nullを「プロパティに値がない」と定義するというあなたの結論は完全に正しいと思います。また、JavaScriptと同じくらい動的な言語では、非常に重要な違いです。アヒルのタイピングの使用は、存在しないプロパティと値を持たないプロパティを区別できる必要があることを意味します。型情報を導出する主な手段です。静的に型付けされた言語では、nullであるフィールドと存在しないフィールドとの間には明確な区別があります。 JavaScriptでもこれは同じです。ただし、実行時にチェックされ、それまで変更できます。

多くの場合、区別があいまいになるため、実装が奇妙であることに同意する必要があります。ただし、JavaScriptでは区別が重要だと思います。 undefinedを割り当てることができることは不可欠です。

JavaScriptで書かれたオンラインRPGに関するブログ投稿を少し前に読んだことを覚えています。オブジェクトをプロトタイプ(クラス、関数など)ではなく、既存のインスタンスのコピーとして作成し、その後変更する例を使用しました。これにより、既存のオブジェクトを変更するときにundefinedがどれほど強力かを理解できましたが、誰が書いたのか覚えていません。

6
Jack Ryan

Javaプログラマーとして、undefinedとnullには大きな違いがあります。JavaScriptのコーディングはそれほどではありません。JavaScriptは強く型付けされておらず、undefinedとnullの違いは自動ちなみに、私はこれらの変換を頻繁に利用しており、JSコードをよりコンパクトで読みやすくしています。

あなたの質問に答えるために、未定義は値が設定されなかったことを意味します。実際には、これは一般的にバグを指します。 yourObject.propertyが未定義の場合、何らかの理由でプロパティを設定しなかったか、まったく存在しないものを探しています。これは、複数のコーダーを含むプロジェクトで作業する場合の本当の問題です。

nullは、「値なし」が明示的に設定されたことを意味します。実際には、このコンテキストでは使用されていないか、値がまだ決定されていないことを、プロパティについて何か教えています。

Javaでは、未定義のフィールドにアクセスしようとすると常に例外が発生します。実際、コンパイラーは、コード内でこれについて警告するようにできます。

3
Steve11235

意味的には、それらは異なることを意味します。 null型は、ドメイン内に1つの値、nullを持ち、プロパティにはこの特定の値が割り当てられる場合があります。未定義は、値が割り当てられていないことを明確に示しています。

3
AnthonyWJones

この例を試してください:

<html>
<head>
    <script type="text/javascript">
        function ShowObjProperties(obj) {
            var property, propCollection = "";

            for(property in obj) {
                propCollection += (property + ": " + obj[property] + "\n");
            }

            alert(propCollection);
        }

        var obj = {
            userid: 3,
            name: 'me!',
            speak: function() { alert('Hi! My name is ' + this.name + ' and my ID is ' + this.userid + '.'); }
        }

        //Shows all properties
        ShowObjProperties(obj);

        //The Speak function is no longer in the list!
        delete obj.speak;
        alert(typeof obj.speak);
        ShowObjProperties(obj);

        //The UserID is still listed, it just has no value!
        obj.userid = null;
        ShowObjProperties(obj);
    </script>
</head>
<body>

</body>
</html>

ここでは、2つの異なるタイプの非常に現実的な用途があると思います。

0
EndangeredMassa

javascriptのイベントパラダイムにプログラムをラップする場合、これは重要な言語機能です。

// a key exists as a placeholder for something
if(obj[name] === null) 
// no key exists int eh hashtable that is in this object
if(obj[name] === undefined)

これは、デフォルトアクションを示すために「nothing」を使用することとは異なるアクションを示す「nothing」を表す値が必要なデータセットを処理する場合に非常に便利です。

filter_func_pt = {
  date:function(d){ return Math.round(d.getTime()/1000);},
  user: null,
}

function transform(obj){
    var ret = {};
    for( var prop in obj){
       var f = filter_func_pt[prop];
       if(f)
          ret[prop] = f(obj);
       else if(filter_func_pt[prop] === null)
         continue;
       else
         ret[prop] == obj;
    }
  return ret;
}

var a = {
   date: new Date(),
   user: 'sam'
   votes: [23, 41, 55] 
};

var b = transform(a);

/* b = {
 *    date: 1298582417
 *    votes: [23, 41, 55]
 * }
 */

上記のコードでは、nullキーワードとndefinedサーバーは非常に明確で異なる目的です。 ndefinedを返すfilter_func_ptオブジェクトで見つからないルックアップは、戻りオブジェクトにプロパティをそのまま追加することを意味します。一方、null値は、値を差し控える、および追加されず、この場合の真の値の存在は、値をretオブジェクトに追加する前に変換するために使用される関数を表します。

0
Fire Crow

結局のところ、JavaScriptの動的な性質です。

事物は、後で追加できるように未定義の場合があります。これが、おそらくJavaScriptが非常に強力で拡張可能な理由です。

nullは美しい

他のすべての種類のライブスクリプトも同様です。

cite:JavaScriptには、基本的に「存在しない」という2つの値があります-未定義とnullです。

なぜあなたは間違ったことを言いたいのですか?!

"null" is "empty Object"「0」が"empty number"であるように。 0、何もありません-それは数値の種類として存在します。 nullも空ですが、「それは」「オブジェクトタイプ」の明確に定義されたものです。

そうではない場合、これらのことを「タイプ」として話すのが一般的です。実際、それらは「カテゴリー」です。しかし、それはもう終わりです。

したがって、「null」は種類のないオブジェクトのタイプであると言うことに固執します。そして、「null」は「私は非常に存在します[!]が、私の種類のコンテンツを持っていません」と言います。

一方、ndefinedにはTypeとKindの両方がありません。ここでndefinedはタイプ定義でもあります。型の未定義の型は、その独特の類型になります。ある種の[「何も」存在せず、「何も」をどのように定義しますか?]質問。

cite:未定義またはnullはコンストラクタ関数から返すことができます。両方とも空のオブジェクトへのコンバータになるためです

あなたはもう一度間違ったことを言うことができました。もちろん、「未定義」はオブジェクトではなく、人間が理解しているプレーンなトークンではありません。しかし、それに反してnullは-であり、次のことを示しています。そのタイプは正しいが、探しているKindが含まれていないか、少なくとも-現時点ではない。後でオブジェクトを\割り当てたときに、私たちを訪ねてください。

cite:私が考えることができる唯一の本当の違いは、一方がNaNに評価され、もう一方が数値コンテキストで0に評価されることです。

前述のように、中核となる区別の要点は次のとおりです。ndefinedは単純なトークンであり、遠い親relativeと同じ「遺伝」素材で構成されているため、文字列、[+ undefined]操作は、それをNaNにアヒル変換します。同様に、nullはもちろん、代わりに正しい種類0\Numberにモーフィングし、ndefinedではなく、文字列にモーフィングします(! )そして、それが代わりにNaNを生成するまさにその理由です。ここで:+ undefined >> + "undefined" >> NaN。数値コンテキストでは明示的な値が必要です。

ブールコンテキストは参照を必要としますが、変換するものは何も見つからず、「false」を生成します。

今すぐカットしましょう...

cite:それでは、undefinedとnullの個別の値の実用的な用途は何ですか?

私はあなたに2つの経験的な例を与えようとし、十分であることを望みます

oElement.onclick >> null

//は、プロパティが存在することを意味します。予想される値のタイプはObjectであり、そのoElementは「onclick」イベントをサポートしています。

oElement.innerText >> ""

//意味-プロパティが存在します;期待される値のタイプはStringです。これは、oElementが「innerText」プロパティをサポートすることを意味します。

両方の場合-「未定義」を受け取った場合、プロパティが存在しないことを意味します。サポートされていないか、実装が間違っています(uaベンダー)。

霜を降りて楽しんでください。

0
user1170379

未定義とnullに関するすばらしい議論を読んだ後、Googleで少し検索するとMozillaドキュメントに移動しました https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null 言及されている-nullは、オブジェクトが期待できるが関連するオブジェクトがない場所で取得されることがよくあります。

ヌルオブジェクトパターンとは異なります https://en.wikipedia.org/wiki/Null_object_pattern

だから、これはNullデータ型を持つのが理にかなっていると思います。

Typeof null // "object"(レガシーの理由で "null"ではない)としても言及されているドキュメント

レガシーの理由がわからない

0
Vishal Bhandare