JavaScriptの等値演算子(==)と同値演算子(===)

サイ本ですが、ようやく第5章を読み終えました。カメのように遅い進みですが、果たして内容を理解できているのやら…。

第5章ですが、同値演算子と等値演算子が登場しました。C#とJava、Rubyでもそれぞれ同値に関する概念が異なっていましたがJavaScriptでも異なるようです。目をこらして読んだのですが、やっぱりいまいちわからないので少し今後のメモとして残したいと思います。

同値演算子(===)

  1. 右辺と左辺で型が異なる場合は同一ではないとする。
  2. 右辺と左辺で同じ値であれば同一とする。少なくともどちらか一方が NaN の場合は同一ではないとする。
  3. 右辺と左辺が文字列で同じ文字列の場合は同一とする。(長さや文字が異なる場合は同一ではないとする。)また、エンコードについては比較前に正規化されている事が前提となる。
  4. 右辺と左辺がともにtrueまたはfalseの場合は同一とする。
  5. 右辺と左辺が共に同一のオブジェクトを参照している場合は同一とする。右辺と左辺が異なるオブジェクトを参照している場合は、オブジェクトのプロパティ同士の比較でも同一ではないとする。
  6. 両方の値がNullまたは両方の値が未定義値であれば同一とする。

どうにも5がうまく理解できません。サンプルを作ってみたのですが、結果は説明とは異なるもの…。

[sourcecode language="JavaScript"]

function Circle(radius){
    this.r = radius;
}

Circle.PI = 3.14;

Circle.prototype.area = function(){return Circle.PI * this.r * this.r;}

function Circle2(radius){
        this.r = radius;
    }

Circle2.PI = 3.14;

Circle2.prototype.area = function(){return Circle2.PI * this.r * this.r;}
// 異なるクラスを生成
var c1 = new Circle(3);
var c2 = new Circle2(3);

// これはfalseとなる
document.write("c1 === c2 => " + (c1 === c2)+ "<br />");

// これはtrueになる…?なんで?
document.write("c1.area === c2.area => " + (c1.area() === c2.area())+ "<br />");

[/sourcecode]

クラスを理解できていないのか、文章を理解できていないのかわかりませんのでとりあえずわからないままにしましょう。

同値演算子(==)

  1. 右辺と左辺が同じ型の場合、同値であれば等しいとする。
  2. 右辺と左辺が異なる型の場合、以下のケースで等しいとする。
    1. 右辺または左辺の一方がNullでもう一方が未定義
    2. 右辺または左辺の一方が数値でもう一方が文字列の場合、文字列を数値に変換し変換した値が一致する
    3. 右辺または左辺の一方がtrueの場合でtrueを1へ変換した結果値が一致する
    4. 右辺または左辺の一方がtrueの場合でfalseを0へ変換した結果値が一致する
    5. 右辺または左辺の一方がオブジェクトでもう一方が数値または文字列の場合でオブジェクトを基本型に変換した結果が一致する
  3. 上記以外の場合は等しくないとする。

こっちは結構素直な内容ですね。

うーん、なかなか理解に苦しむところもありますがとりあえず進めてから戻ってくることにしましょう。

 

2011/12/30 追記

見直してみたところ、プロパティをメソッドとして呼んでいたためか、下記のように修正したところ期待したとおりの結果を得ることができました。

[sourcecode language="JavaScript"]

...

// これはfalseになる
//document.write("c1.area === c2.area => " + (c1.area() === c2.area())+ "<br />");
document.write("c1.area === c2.area => " + (c1.area === c2.area)+ "<br />");

[/sourcecode]