124

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

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

プリミティブな値であり、オブジェクトであるため、 nullbecauseの必要性があると考えたことがあります。実際には、どちらもプリミティブ値です。つまり、どちらも空のオブジェクトに変換されるため、コンストラクター関数から返すことも返すこともできません (コンストラクターで失敗を宣言するにはエラーをスローする必要があります)。undefinednulltypeof null'object'undefinednull

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

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

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

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

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

私は実際にはundefined、もう使用していないが、したくないプロパティの値を設定解除したいときに使用しますdeletenull代わりに使うべきですか?

4

12 に答える 12

87

問題は、実際には「なぜ JS に null 値があるのか​​」ということではありません。ほとんどの言語には何らかの null 値があり、一般的に非常に便利であると考えられています。

問題は、「なぜJSに未定義の値があるのか​​」ということです。主な使用場所:

  1. 宣言var x;しても代入しない場合xは未定義になります。
  2. 関数が宣言するよりも少ない引数を取得する場合。
  3. 存在しないオブジェクト プロパティにアクセスしたとき。

null(1) と (2)* の場合も同様に機能したはずです。(3) は実際にはすぐに例外をスローする必要がありますが、例外をスローしないという事実は、undefined後で失敗するこの奇妙なものを返す代わりに、デバッグを困難にする大きな原因です。

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

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

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

はい。undefined他の言語が代わりに例外をスローする可能性がある場合に通知するための特別な値として保持します。

null何かを設定するとnullエラーが発生する可能性がある一部の IE DOM インターフェイスを除いて、一般的にはの方が優れています。多くの場合、この場合、空の文字列に設定するとうまくいく傾向があります。

于 2009-01-21T00:00:05.297 に答える
38

hereで最もよく説明されていますが、要約すると:

undefined は型と値の欠如であり、null は値の欠如です。

さらに、単純な「==」比較を行っている場合、その通りです。結果は同じです。しかし、型と値の両方を比較する === を試してみると、違いに気付くでしょう。

于 2009-01-20T16:18:16.103 に答える
18

多くの人が提案した唯一の理由 (「そのような変数/プロパティがないことを意味する」) は、少なくとも JavaScript では有効ではないため、nullとの両方を使用する理由はないと思います。変数/プロパティが存在するかどうかはわかりません。undefinedundefinedundefined

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 作成者の本来の意図である可能性があります。しかし、実装はそのようにはなりませんでした。

于 2012-10-18T19:38:23.367 に答える
6

両方が必要になる可能性は十分にあります。たとえば、WMI に対してクエリを実行すると、クラスが null 値を持つプロパティを返す可能性があります。それらは定義されており、たまたまその時点で null を保持しています。

于 2009-01-20T16:17:52.763 に答える
6

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

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

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

于 2009-01-20T17:45:24.397 に答える
3

意味的には、それらは異なることを意味します。タイプ null は、そのドメインに null という値を 1 つだけ持ち、プロパティにはこの特定の値を割り当てることができます。未定義は、割り当てられた値がまったくないことを表します。

于 2009-01-20T16:21:23.040 に答える
3

Java プログラマーとして、未定義と null の間には大きな違いがあることに気づきました。JavaScript は厳密に型指定されておらず、実行時に頻繁に実行される自動変換によって undefined と null の違いがぼやけているため、JavaScript のコーディングはそれほど多くありません。ところで、私はこれらの変換を頻繁に利用しています。それらは私の JS コードをよりコンパクトで読みやすくします。

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

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

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

于 2012-04-11T14:25:06.083 に答える
0

ヌルは美しい

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

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

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

「 0」が「空の数値」であるように、 「null」「空のオブジェクト」です。0 は何もありませんが、数値の型として存在します。 もちろんnullも空ですが、「それは」であり、Object Typeの明確に定義されたものです。

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

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

undefinedには Type と Kind の両方がありませんが、 undefinedはその Type 定義でもあります。型の未定義型は、その独特の類型になります。[「何もない」というのはありますか? また、「何もない」とはどのように定義しますか?] という質問です。

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

あなたはまた間違ったことを言うことに成功しました。もちろんそうではありません。「未定義」はオブジェクトではなく、人間が理解できるプレーンなトークンです。しかし、そのnullに反して、それはあなたにそれを伝えています:そのタイプは正しいですが、あなたが探している種類はその中に含まれていないか、少なくとも - 現時点では含まれていません。後で何かオブジェクトを配置\割り当てするときに私たちに会いに来てください。

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

前述のように、それはそれらの核となる違いの全体的なポイントになります: undefinedは単純なトークンであり、遠い親戚である文字列と同じ「遺伝的」素材で構成されているため、 [ +undefined ] 操作はそれをダック変換しますNaN、同様に null はもちろん、代わりに正しい種類 0 \Number に変形し、文字列に変形するundefinedとは対照的に (!これは空ではありません!)、まさにそれが代わりにNaNを生成する理由です。ここで: +undefined >> +"undefined" >> NaN。数値コンテキストは明示的な値を期待するためです。

Boolean コンテキストは参照を予期しますが、変換するものが何も見つからず、「false」が返されます。

さぁ、切り抜けよう…

cite: もう一度: undefined と null の個別の値の実用的な用途は何ですか?

経験的な例を 2 つだけ挙げて、十分であることを願っています。

oElement.onclick >> null

//つまり、プロパティが存在します。期待される値は Type: Objectであり、その oElement は「onclick」イベントをサポートしています!

oElement.innerText >> ""

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

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

霜にとどまり、楽しんでください。

于 2012-02-09T01:16:11.200 に答える
0

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

<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 つの異なるタイプの非常に実用的な用途があると思います。

于 2009-01-20T17:04:05.260 に答える
0

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

後で追加できるように、未定義の場合があります。これが、javascript が非常に強力で拡張可能である理由です。

于 2009-01-20T17:30:40.310 に答える
0

プログラムを 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)

これは、既定のアクションを示すために「何もない」を使用するのとは異なるアクションを示すために「何もない」を表す値が必要な一連のデータを扱う場合に非常に便利です。

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キーワードと未定義のサーバーが非常に明確で異なる目的を持っています。未定義を返す filter_func_pt オブジェクトに見つからないルックアップは、返されるオブジェクトにプロパティをそのまま追加することを意味します。一方、null値は、値を保留し、追加しないことを示し、この中に真の値が存在することを示します。 case は、値をretオブジェクトに追加する前に変換するために使用される関数を表します。

于 2011-02-24T21:25:06.867 に答える
0

undefined と null に関する驚くべき議論を読んだ後、Google で少し検索すると Mozilla Documentations 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 // "オブジェクト" (従来の理由から "null" ではありません) としても言及されています

レガシーの理由が不明

于 2018-03-17T10:36:23.530 に答える