22

したがって、JavaScriptでのnullとundefinedの実装に関する大きな議論/討論/議論の後、実装の背後にある理由と、状況によっては異なる理由を誰かに説明してもらいたいと思います。私が困っているいくつかの特定のポイント:

  • null == undefinedに評価しますtrue
  • null + 11に等しいがundefined + 1等しいNaN
  • if(!null)trueとif(null)評価され、falseと評価されますが、falseと評価null == falseされます。

仕様を読み、結果がどのように達成されるかを知っています。これが仕様であることを示すパラダイムと理由を探しています。これらのポイントのいくつか、特に最初のポイントを考えると、2番目のポイントは非常に一貫性がないと感じています。

4

4 に答える 4

10

短くて甘いバージョンは、JavaScriptがNetscapeチームによって非常に迅速に設計および実装されており、あなたが指摘したようないくつかの矛盾があったことです。

Internet Exploderチームは、JSを正確にコピーするために最善を尽くし、不整合もコピーされるまで、JSを非常にうまく処理しました。NetscapeがJSを標準化するために行ったとき、ECMAScript MSはその一部であり、基本的に、古いコード(既存のシステムの慣性)を壊すため、標準を変更することは許可されていないと述べました。矛盾は標準化されました、そしてそれはそれでした。

Douglas Crockfordは、これらの問題のいくつかについて非常に優れた一連の講演を行っています

于 2011-08-09T18:16:51.890 に答える
8

何よりもまず、多くの言語は、そのような同様の目的のために2つのメソッドを持たずに逃げますが、Javascriptでは、目的は多少重複していますが、明確に機能します。「なぜ両方あるの?」以前にここで尋ねられました、そして私はこの答えがこれをかなりよく説明しているのを見つけます。TL; DR:Javascriptには、初期化されていない値ではなく、存在しない値を生成する特定の言語関数があります。

  • delete'd値
  • オブジェクトに存在しないプロパティ
  • 関数パラメーターがありません

あなたの質問のように見える矛盾については、それらは実際には仕様によって非常に簡単に説明されます。 (おそらく激しく反対する人もいるでしょうが、説明はエレガントであると主張することさえできると思います。)

それぞれに個別に対処する:

  • null==undefinedはtrueと評価されます

これについての最良の説明については、この回答を参照してください。要するに、抽象的等式比較仕様は、それらが(厳密ではないが)等しいと言っています。


  • null + 1は1に等しいが、未定義+1はNaNに等しい

演算子は単項+(数値変換)演算子または加算+演算子のいずれかとして機能しますが、どちらも引数をToNumber仕様にルーティングします。

引数タイプ—結果
未定義— NaN
Null — +0
ブール値—引数がtrueの場合、結果は1になります。引数がfalseの場合、結果は+0になります。
数値—結果は入力引数と等しくなります(変換なし)。

言い換えれば、にnull + 1なり+0 + 1、にundefined + 1なります。NaN + 1これは常にNaNです。


  • if(!null)はtrueと評価され、if(null)はfalseと評価されますが、null==falseはfalseと評価されます。

ご存知のよう!に、Logical Not演算子は、式に対してToBoolean 変換を実行します。これは一種の切り捨てです。

ifステートメント( )は、exprif (expr)に対して暗黙のブール比較を実行します。したがって、上記の両方のステートメントでexprのタイプを見てください。if

  • if (!null)expr!null、論理否定演算子(!)の結果を考えると、ブール値です。
  • if (null)exprnull、変換が実行されなかったことを意味します。

論理否定演算子は実際の変換を実行するため、他の場合にも同じことが起こり、実際には次のように見える論理的な矛盾ではありません。

  • if (!"" == !undefined)= true
  • if ("" == undefined)=もちろんfalse 。
于 2011-08-09T18:32:22.950 に答える
4

それらは、さまざまな目的で使用される完全に異なるオブジェクトとして最もよく考えられています。

null「価値がない」ために使用されます。言語ではめったに使用されませんが、ホスト環境では「価値がない」ことを示すためによく使用されます。たとえば、存在しない要素の場合はdocument.getElementById戻ります。null同様に、sのIEのみのプロパティはonreadystatechange、ではなくに設定されます。これは、プロパティが存在するにもかかわらず、現在は設定されていないことを示します。一般に、の代わりに独自のコードで使用し、次の場合に使用することをお勧めします。HTMLScriptElementnullundefinednullundefinedundefined

undefined「設定されていない、または存在しない」ために使用されます。これは多くの場合「デフォルト」です。たとえば、未定義のプロパティへのアクセス( IE以外のブラウザonreadystatechangeHTMLScriptElement場合など)、ステートメントのないメソッドからのデフォルトの戻り値return、関数がそれよりも少ない引数で呼び出された場合の関数パラメータのデフォルト値宣言など。

このように、null何か特別なことを意味する「有効な値」と考えると便利です。一方、それundefinedは言語レベルのものです。

確かに、これらの推論が完全に当てはまらないいくつかのエッジケースがあります。それらは主にレガシーの理由によるものです。しかし、違いがあり、それはある程度意味のあるものです。


特にあなたの問題点に関しては、それらは主に==オペレーターの悪または型強制から生じます:

  • null == undefined==:演算子は基本的に、当時は直感的に見えた下位互換性ルールの混乱であるため、使用しないでください。
  • null + 1 === 1vs undefined + 1 === NaN.:オペレーターは、評価する前に+型強制を行います。Numberそしてnull0+null === 0)に強制しますが、 ( )undefinedに強制します。NaNisNaN(+undefined) === true
  • if (!null)、、 :ifはif (null)null == falseその引数の「真実性」または「偽り性」を評価します。これは、のルールの混乱とは関係ありません==null偽りであり、!null真実ですが、のルールは許可し==ませんnull == false
于 2011-08-09T18:17:57.260 に答える
1

null == undefined確かにtrueと評価されますが、null === undefinedfalseと評価されます。

これら2つのステートメントの違いは、等式演算子です。JavascriptのDouble-equalは、2つのアイテムを比較する前に同じタイプに変換します。の場合null == undefined、これはnull、比較が行われる前にが未定義の変数に変換されることを意味します。したがって、等式です。

文字列と整数でも同じ効果を示すことができます"12" == 12。trueですが、"12" === 12falseです。

この例は、それぞれに1つ追加することについて、次のポイントを議論するためのより簡単な方法を提供します。上記の例では、整数に1を追加すると明らかにが得られ13ますが、文字列を使用すると文字列"12" + 1が得られます"121"。これは完全に理にかなっており、他の方法では必要ありませんが、double-equal演算子を使用すると、元の2つの値は等しいと報告されます。

ここでの教訓は、異なるタイプの変数を比較する特別な必要がない限り、常にdouble-equalよりもtriple-equal演算子を使用することです。

あなたの最後のポイントはnull、一般的な気まぐれな性質を示しています。null許容型のデータベースフィールドを操作しようとしたことがある人なら誰でもわかるように、これは独特の獣です。Nullは、コンピュータサイエンスで非常に具体的な定義を持っており、複数の言語で同様の方法で実装されているため、説明する状況は、特別なJavascriptの奇妙さではありません。ヌルは変です。の代替名のように動作することを期待しないでくださいfalse。そのようには機能しません。組み込みのinfinity値は、同様に奇妙な方法で、同様の理由で動作する可能性があります。

ただし、Javascriptには奇妙な部分があります。http://wtfjs.com/を読むことに興味があるかもしれません。このサイトには、Javascriptが行う奇妙なことのすべてのエントリがあります。それらのかなりの数がandと関係がnullありundefined(組み込みオブジェクトの値を再定義することが実際に可能であることをご存知undefinedですか?!)、それらのほとんどには、実際に何が起こっているのか、そしてその理由についての説明が付いています。物事がそのように機能する理由を示すのに役立つかもしれませんし、避けるべきことを示すのに間違いなく役立ちます!そして、他に何もないとしても、人々が貧しい言語に投げかけようとした虐待のいくつかを見るのは、楽しい読み物になります。

于 2011-08-09T18:31:23.703 に答える