ホームページ >ウェブフロントエンド >jsチュートリアル >邪悪な双子を恐れないでください - setepoint
JavaScript開発者のDouglas Crockfordは、かつてJavaScript ==
および!=
と==
を調べ、それらがどのように機能するかを説明し、それらをよりよく理解するのに役立ちます。 !=
キーポイント
==
キャストなしの直接的なタイプと値の比較には、いつ使用するかを使用してください。タイプが動的に変更される可能性のある値をキャストまたは比較する必要がある場合は、!=
および===
および!==
比較の間にJavaScriptがどのようにタイプをキャストするかに精通しているため、結果をより正確に予測し、一般的な落とし穴を回避します。 ==
!=
==
!=
とは恐ろしくありませんが、JavaScriptのタイプキャストルールを効果的かつ安全であるために使用するためには、それを使用するために十分に理解する必要がありますローカル。 ==
問題!=javaScript言語には、==
および!=
オペレーターを理解するのは難しくありません。 2つのオペランドタイプが同じで、値が同じである場合、を返し、を返します。ただし、値またはタイプが異なる場合、==
を返し、!=
を返します。 2つのオペランドタイプが同じ場合、
演算子は同じように動作します。ただし、タイプが異なる場合、JavaScriptは1つのオペランドを別のタイプにキャストして、比較前にオペランドを互換性のあるものにします。結果は、次のようにしばしば混乱しています
===
!==
可能なブール値は2つしかないため、式の1つを==
として計算する必要があると思うかもしれません。ただし、それらはすべて!=
として計算されます。パス関係(aがbに等しく、bがcに等しい場合)が適用する必要があると仮定すると、追加の混乱が発生します。
<code class="language-javascript">"this_is_true" == false // false "this_is_true" == true // false</code>
この例は、==
にトランサテン性が欠けていることを示しています。空の文字列が番号0に等しく、数値0が文字0で構成される文字列に等しい場合、空の文字列は0で構成される文字列に等しくなければなりません。しかし、そうではありません。オペランドを==
または!=
を介してオペランドを比較するときに互換性のないタイプに遭遇した場合、JavaScriptは1つのタイプを別のタイプにキャストして、比較可能にします。逆に、===
と!==
を使用すると、タイプキャストを実行することはありません(パフォーマンスのわずかな改善につながります)。さまざまな種類のため、===
は常に2番目の例でfalse
を返します。 JavaScriptがオペランドをさまざまなタイプにキャストする方法を制御するルールを理解するため、2つのオペランドタイプが適用する前に2つのオペランドタイプが互換性があるようにすることができます。これらの演算子を使用します。次のセクションでは、==
および!=
オペレーターで使用されるキャストルールを検討します。 ==
!=
==
!=
および
==
と!=
の作業が、ECMAScript言語の仕様をどのように研究するかを学ぶための最良の方法です。このセクションでは、ECMAScript 262に焦点を当てています。仕様のセクション11.9では、平等演算子を紹介します。 および
および==
に表示されます。 (第一世代とは異なり、第2世代は!=
演算子を回避します。)以下に示す==
世代を確認しましょう。 !=
EqualityExpression
EqualityExpressionNoIn
この世代によれば、等しい式はリレーショナル式、またはリレーショナル式に等しい等しい式、またはリレーショナル式などに等しくない等しい式のいずれかです。 (私はこの記事に関連していないin
とEqualityExpression
を見落としていました。)セクション11.9.1は、
<code class="language-javascript">'' == 0 // true 0 == '0' // true '' == '0' // false</code>
生産式==
は次のように計算されます
!=
===
!==
を計算の結果とします。 ==
beおよび。
EqualityExpression : EqualityExpression == RelationalExpression
を計算の結果とします。
- 。
lref
letEqualityExpression
belval
抽象的な平等比較を実行した結果を返しますGetValue(lref)
。 (11.9.3を参照してください。)rref
RelationalExpression
セクション11.9.2は、どのように機能するかについての同様の情報を提供します:rval
生産式GetValue(rref)
は次のように計算されます
- let
lref
を計算の結果とします。EqualityExpression
- be
lval
。GetValue(lref)
- を計算の結果とします。
berref
RelationalExpression
let- 。
抽象的な平等比較を実行した結果とするrval
GetValue(rref)
- とします。 (11.9.3を参照してください。)
isr
rval != lval
if- 、return
r
。それ以外の場合は、true
を返します。false
true
は、lref
およびrref
オペレーターの左側と右側に参照されます。各参照は、対応する値を返すために==
内部関数に渡されます。セクション11.9.3:!=
に示されている抽象的な平等比較アルゴリズムによって、GetValue()
および==
作業がどのように指定されているかの中核
!=
、ここでと
x == y
は値であり、x
またはy
になります。この比較は、次のように実行されます:true
- if
Type(x)
がType(y)
と同じ場合、
- if
Type(x)
isUndefined
、returntrue
。- if
Type(x)
isNull
、returntrue
。- if
Type(x)
isNumber
、次に
- if
x
isNaN
、returnfalse
。- if
y
isNaN
、returnfalse
。x
およびy
が同じ数値値である場合、true
を返します。- です。
x
の場合、y
は0、true
は-0、return- が返されます。
x
y
が-0、true
が0の場合、- 。
false
return- を返します。
Type(x)
String
isx
である場合、y
およびtrue
がまったく同じ文字シーケンス(対応する位置の同じ長さと同じ文字)である場合、false
が返されます。それ以外の場合は、- 同じオブジェクトを参照している場合、
Type(x)
ifBoolean
の場合、x
とy
の両方である場合、または両方の場合、true
の両方である場合、false
を返します。それ以外の場合は、true
を返します。false
- および
x
を参照してくださいy
。それ以外の場合は、true
を返します。false
- is
ifx
およびnull
isy
、undefined
を返します。true
- is
x
およびundefined
isy
、null
を返します。true
- is
isType(x)
andNumber
isType(y)
の場合、比較の結果が返されます。String
x == ToNumber(y)
- and
の場合、比較の結果が返されます。Type(x)
isString
の場合、比較の結果が返されます。Type(y)
Number
ToNumber(x) == y
の場合、Type(x)
Boolean
の場合、ToNumber(x) == y
の場合、比較の結果が返されます。- is
Type(y)
isBoolean
またはx == ToNumber(y)
および- の場合、比較の結果が返されます。
の場合、比較の結果が返されます。Type(x)
String
Number
isType(y)
andObject
isx == ToPrimitive(y)
または- は
Type(x)
returnObject
。Type(y)
String
Number
ToPrimitive(x) == y
ステップ1オペランドタイプは、このアルゴリズムで実行されると同じです。- に等しく、
に等しいことを示しています。また、false
がNaN
(非番号)、2つの同一の値が等しく、0は0に等しい、同じ長さの2つの文字列が等しいものは等しいものは等しく、true
true
はfalse
に等しく、同じオブジェクトへの2つの参照が等しくなります。手順2と3は、false
を返す理由を示します。 JavaScriptは、これらの値が同じであると考えています。ステップ4から始めて、アルゴリズムが興味深いものになります。このステップでは、null != undefined
値とfalse
値の平等に焦点を当てています。最初のオペランドがNumber
であり、2番目のオペランドがString
である場合、2番目のオペランドはNumber
の内部関数を介してString
に変換されます。式ToNumber()
は再帰を意味します。ステップ5はステップ4に相当しますが、最初のオペランドにはタイプNumber
があり、型x == ToNumber(y)
に変換する必要があります。手順6および7ブールオペランドをString
タイプに変換して再帰的に変換します。他のオペランドがブール値である場合、このアルゴリズムが次に実行されるときにNumber
に変換され、再び再発します。パフォーマンスの観点から、2つの再帰的な手順を避けるために、両方のオペランドがブール型であることを確認することをお勧めします。ステップ9は、オペランドのタイプがNumber
の場合、オペランドがNumber
内部関数を介して元の値に変換され、アルゴリズムが再帰的に変換されることを示しています。最後に、アルゴリズムは、2つのオペランドが等しくなく、ステップ10でObject
を返すことを考慮します。詳細ではありますが、抽象的な平等比較アルゴリズムは非常に簡単に理解できます。ただし、アルゴリズムを完全に理解するために内部作業を公開する必要がある内部関数のペアを参照しています。ToPrimitive()
関数は、そのパラメーターをfalse
に変換し、セクション9.3で説明します。次のリストは、考えられる非数字のパラメーターと同等の返品値をまとめたものです。
- パラメーターが
Undefined
の場合、NaN
を返します。- パラメーターが
Null
の場合、0を返します。- パラメーターがブール値
true
の場合、1を返します。パラメーターがブール値false
の場合、0を返します。- パラメータータイプが
Number
の場合、入力パラメーターが返されます - 変換はありません。- パラメーターのタイプが
String
の場合、セクション9.3.1「文字列タイプのトナンバー」が適用されます。構文で示される文字列パラメーターに対応する値を返します。パラメーターが示されている構文と一致しない場合は、NaN
を返します。たとえば、パラメーター「xyz」はNaN
を引き起こします。さらに、パラメーター「29」の結果、29が返されます。- パラメーターのタイプが
Object
の場合、次の手順を適用してください。let
- be
returnprimValue
。ToPrimitive(输入参数, 提示Number)
- 。
ToNumber(primValue)
関数は、入力パラメーターとオプションの
ToPrimitive()
パラメーターを受け入れます。入力パラメーターは、非オブジェクトタイプに変換されます。オブジェクトを複数のプリミティブタイプに変換できる場合は、PreferredType
オプションのToPrimitive()
プロンプトを使用して、優先タイプにバイアスをかけます。コンバージョンは次のように実行されます:PreferredType
入力パラメーターが
を含むさまざまな表現を提供し、徐々にアルゴリズムの手順を完了することにより、練習に目を向けます。- の場合、入力パラメーター(
入力パラメーターがUndefined
)が返されます - 変換はありません。Undefined
- の場合、入力パラメーター(
入力パラメーターのタイプがNull
)が返されます - 変換はありません。Null
- の場合、入力パラメーターを返します - 変換はありません。
入力パラメーターのタイプがBoolean
- の場合、入力パラメーターを返します - 変換はありません。
入力パラメーターのタイプがNumber
- の場合、入力パラメーターを返します - 変換はありません。
入力パラメーターのタイプがString
- の場合、入力パラメーターに対応するデフォルト値が返されます。オブジェクトの内部メソッドを呼び出し、オプションの
とObject
プロンプトを渡すことにより、オブジェクトのデフォルト値を取得します。[[DefaultValue]]
の動作は、すべてのネイティブECMAScriptオブジェクトのセクション8.12.8で定義されています。PreferredType
[[DefaultValue]]
このセクションでは、非常に多くの理論を紹介します。次のセクションでは、
==
!=
邪悪な双子を理解してくださいECMAScriptの仕様に従ってと
がどのように機能するかを理解したので、これらの演算子が関与するさまざまな表現を調査して、この知識を利用してみましょう。これらの表現を評価する方法を説明し、それらがまたは
==
である理由を調べます。私の最初の例については、記事の冒頭の近くで導入された次の式ペアを考えてみましょう。!=
true
抽象的な平等比較アルゴリズムに従って、次の手順に従ってこれらの式を評価します。タイプが異なるため、
- ステップ1をスキップします。
typeof "this_is_true"
"string"を返し、typeof false
またはtypeof true
は「boolean」を返します。- 手順2から6をスキップします。これは、オペランドの種類と一致しないために適用できません。ただし、適切なパラメーターには
Boolean
があるため、ステップ7は適用されます。式は"this_is_true" == ToNumber(false)
および"this_is_true" == ToNumber(true)
に変換されます。ToNumber(false)
は0を返し、ToNumber(true)
1を返します。これにより、式がそれぞれ"this_is_true" == 0
および"this_is_true" == 1
に単純化されます。この時点で、アルゴリズムは再帰的に。- 手順1から4をスキップします。これは、オペランドの種類と一致しないために適用できません。ただし、ステップ5は、左オペランドのタイプが
String
であり、右オペランドのタイプがNumber
であるために適用されます。式はToNumber("this_is_true") == 0
およびToNumber("this_is_true") == 1
に変換されます。ToNumber("this_is_true")
NaN
を返します。これは、それぞれNaN == 0
とNaN == 1
に式を簡素化します。この時点で、アルゴリズムは再帰的に。- ステップ1に移動します。これは、
NaN
、0、および1のタイプがすべてNumber
であるためです。適用されない手順1.aおよび1.bをスキップします。ただし、ステップ1.C.は、左のオペランドがNaN
であるために適用されます。アルゴリズムは、各元の式の値としてfalse
(NaN
はそれ自体を含むものと等しくない)を返すようになり、スタックをバックトラックして再帰を完全に終了します。私の2番目の例(「Galaxy Wandering Guide」での人生の意味の説明に基づいて)は、
の数字とオブジェクトを比較します。==
:true
:<code class="language-javascript">"this_is_true" == false // false "this_is_true" == true // false</code>次の手順では、JavaScriptが抽象的な等式比較アルゴリズムを使用して式の値として取得する方法を示しています。
私の最後の例では、次のシーケンスがトランジニティを示さない理由を調べましょう。
- 手順1から8をスキップします。これは、オペランドの種類と一致しないために適用できません。ただし、ステップ9は、左オペランドのタイプが
Object
であり、右オペランドのタイプがNumber
であるために適用されます。式はToPrimitive(lifeAnswer) == 42
に変換されます。- 手順1から4をスキップします。これは、オペランドの種類と一致しないために適用できません。ただし、ステップ5は、左オペランドのタイプが
ToPrimitive()
プロンプトなしでlifeAnswer
内部メソッドを呼び出してください。 ECMAScript 262仕様のセクション8.12.8によれば、[[DefaultValue]]
は「42」を返す[[DefaultValue]]
メソッドを呼び出します。式はtoString()
に変換され、アルゴリズムは再帰的です。"42" == 42
- であり、右オペランドのタイプが
String
であるために適用されます。式はNumber
に変換されます。ToNumber("42") == 42
- は42を返し、式は
ToNumber("42")
に変換されます。アルゴリズムは、ステップ1.C.IIIを再発および実行します。数字は同じであるため、42 == 42
が返され、再帰的に拡張されます。true
true
次の手順では、JavaScriptが抽象的な等式比較アルゴリズムを使用してfalse
の値として取得する方法を示しています。<code class="language-javascript">"this_is_true" == false // false "this_is_true" == true // false</code>ステップ5を実行して
String -numericLiteral ::: [empty] 's mv [数学的値]は0です。つまり、空の文字列の値は0です。)true
になり、'' == 0
に変換され、アルゴリズムが再帰的に変換されます。 (仕様のセクション9.3.1では、になり、
- ステップ1.C.IIIを実行します。これは、0を0と比較し、
:ToNumber('') == 0
を返します(および再帰を展開します)。0 == 0
次の手順では、JavaScriptが抽象的な等式比較アルゴリズムを使用して- の値として取得する方法を示しています。
ステップ4を実行してtrue
に変換され、アルゴリズムが再帰的に変換されます。
を返します(および再帰を展開します)。true
0 == '0'
ステップ1.C.IIIを実行します。これは、0を0と比較し、結論
- を取得します。 2つの文字列の長さは異なるため(0と1)、
0 == ToNumber('0')
最後に、javaScriptは抽象的な等式比較アルゴリズムでステップ1.dを実行して、0 == 0
の値として- を返します。
true
を使用する必要がある理由を疑問に思うかもしれません。結局のところ、以前の例では、これらの演算子は、型鋳造と再帰のために
true
'' == '0'
false
とおよびオペレーターよりも遅くなる可能性があることが示されています。場合によっては利点がないため、および
を使用することをお勧めします。次の例を考えてみましょう:<code class="language-javascript">"this_is_true" == false // false "this_is_true" == true // false</code>これらの例は、
typeof
演算子はString
値を返します。String
値は別のString
値( "オブジェクト")と比較されるため、型キャストは発生しません。たぶん、==
に遭遇したことがないJavaScriptの初心者は、そのようなコードがより明確になるでしょう。同様に、次のコードスニペットではタイプキャストを必要としません(両方のオペランドのタイプは===
)ため、===
はNumber
:!=
と同じくらい効率的です。!==
<code class="language-javascript">'' == 0 // true 0 == '0' // true '' == '0' // false</code>とが鋳造を必要としない比較に適していることを示しています。オペランドのタイプが異なる場合、
のFAQ javascriptの==
および!=
が予期しない値ではなく===
を返すため、最良の選択です(例:!==
false
)。オペランドのタイプが同じ場合、false == ""
およびtrue
を使用しない理由はありません。たぶんそれは邪悪な双子を恐れるのをやめる時であり、あなたがそれらを理解したら、彼らは邪悪ではありません。==
JavaScriptの平等と比較演算子(FAQ)!=
との違いは何ですか?
JavaScriptでは、および
オペレーター(厳密な平等演算子と呼ばれる)は、型キャストを実行しません。値とタイプを同時に比較します。つまり、2つの値タイプが異なる場合、JavaScriptはそれらが不平等であると見なされます。==
は比較演算子です。ただし、値を比較する方法が異なります。===
オペレーター(ルーズ平等演算子とも呼ばれます)は、比較前にタイプキャストを実行します。これは、2つの異なるタイプの値を比較する場合、JavaScriptは比較を実行する前に1つのタイプを別のタイプに変換しようとすることを意味します。一方、の代わりに
==
javascriptで===
の代わりに==
を使用する必要があるのはなぜですか?===
JavaScriptでは、の代わりに
を使用すると、それらは異なるタイプであるため、不平等と見なされます。===
を使用することをお勧めします。これは、より厳格な比較を提供するためです。つまり、タイプのキャストと値とタイプのチェックを実行しないことを意味します。これは、さまざまなタイプの値を比較する場合、予期しない結果を回避するのに役立ちます。たとえば、JavaScriptは==
を使用する場合、数値0と空の文字列「「等しい」と見なされます。これは、比較前にタイプを変換するためです。ただし、
===
javascriptのタイプキャストとは何ですか?==
JavaScriptの型キャストとは、あるデータ型から別のデータ型に自動または暗黙的に変換されることを指します。これは、オペレーターがさまざまな種類のオペランドに使用されている場合、または何らかのタイプが必要な場合に発生します。たとえば、ゆるい平等オペレーター(==
)を使用する場合、JavaScriptは比較する前にオペランドを一般型に変換しようとします。===
JavaScriptはオブジェクトの比較をどのように処理しますか?
javascriptでは、オブジェクトは値ではなく参照によって比較されます。これは、2つのオブジェクトがまったく同じプロパティと値を持っていても、メモリ内の異なるオブジェクトを参照するため、等しいとは見なされないことを意味します。オブジェクトが等しいと見なされる唯一のケースは、まったく同じオブジェクトを参照することです。
javascriptの
==
と!=
の違いは何ですか?javascriptの
==
および!=
は、JavaScriptの比較演算子です。==
オペレーターは、2つのオペランドの値が等しいかどうかを確認し、必要に応じてタイプキャストを実行します。一方、!=
オペレーターは、2つのオペランドの値が等しくないかどうかを確認し、必要に応じてタイプキャストを実行します。
===
と!==
の違いは何ですか?
===
および!==
は、JavaScriptの比較演算子です。===
演算子は、値とタイプの両方を考慮して、2つのオペランドの値が等しいかどうかを確認します。一方、!==
演算子は、値とタイプの両方を考慮して、2つのオペランドの値が等しくないかどうかをチェックします。JavaScriptの2つの配列を比較する方法は?
javascriptでは、アレイはオブジェクトであり、値ではなく参照によって比較されます。つまり、2つの配列に同じ順序で同じ要素が含まれていても、メモリ内の異なるオブジェクトを参照するため、等しいとは見なされません。コンテンツで2つの配列を比較するには、各要素を個別に比較する必要があります。
javaScriptは
JavaScriptでは、null
とundefined
の比較をどのように処理しますか?および
null
は、両方とも欠損値を表しているため、ゆるく等しい(undefined
)と見なされます。ただし、タイプが異なるため、厳密に等しくありません()。 ==
===
JavaScriptの比較演算子の優先順位は何ですか?JavaScriptでは、比較演算子の優先度レベルと同じです。それらは左から右に計算されます。ただし、算術演算子やビットワイズ演算子よりも優先度が低いが、論理演算子よりも高いことに注意することが重要です。
JavaScriptの文字列を使用して比較演算子を使用できますか?
はい、JavaScriptの文字列を持つ比較演算子を使用できます。 JavaScriptは、文字列を比較するときに語彙(辞書)順序を使用します。ただし、大文字は小文字が小さいため、小文字よりも「小さい」と見なされていることに注意することが重要です。
以上が邪悪な双子を恐れないでください - setepointの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。