2022/03/12(土) JSprimer(演算子②~比較演算子~)

前回の記事の続きです。

比較演算子

❶厳密等価演算子(===)

厳密等価演算子は、左右の2つのオペランドを比較します。 同じ型で同じ値である場合に、trueを返します。

// 同じ型で同じ値である場合にtrueを返す
console.log(1 === 1); // => true
console.log(1 === "1"); // => false
  • 比較するオペランドがどちらもオブジェクトの場合、 オブジェクトの参照が同じであれば、trueを返します。
  • 下記の例では、空のオブジェクトリテラル({})同士を比較しています。
  • オブジェクトリテラルは、その都度、新しいオブジェクトを作成します。
  • つまり、オブジェクトリテラルは、異なる参照のオブジェクトを毎回作成するということです。
  • そのため、異なるオブジェクトを参照する変数を===で比較するとfalseを返します。
// {} は新しいオブジェクトを作成している
const objA = {};
const objB = {};
// 生成されたオブジェクトは異なる参照となる
console.log(objA === objB); // => false
// 同じ参照を比較している場合
console.log(objA === objA); // => true


// objAとBどちらもobject型
console.log(typeof objA);  // => object
console.log(typeof objB);  // => object

❷厳密不等価演算子(!==)

厳密不等価演算子は、左右の2つのオペランドを比較します。 異なる型または異なる値である場合に、trueを返します。

// 異なる型か異なる値である場合に、trueを返す
console.log(1 !== 1); // => false
console.log(1 !== "1"); // => true

❸等価演算子(==)

  • 等価演算子==)は、2つのオペランドを比較します。
  • 同じデータ型のオペランドを比較する場合は、厳密等価演算子===)と同じ結果になります。
  • しかし、等価演算子==)はオペランド同士が異なる型の値であった場合に、 同じ型となるように暗黙的な型変換が行われてから比較します。
  • この暗黙的な型変換は、バグを引き起こすことがあるため、注意が必要です。
  • 等価演算子(==)は、nullundefinedを比較する時にだけ使うようにしましょう。
  • その他の比較の際は厳密等価演算子を使うことを推奨します。
// 同じ型同じ値の場合はtrueを返す
console.log(1 == 1); // => true
console.log("str" == "str"); // => true

// 同じ型で異なる値の場合はfalseを返す
console.log("JavaScript" == "ECMAScript"); // => false

// オブジェクトは参照が一致しているならtrueを返す
// {} は新しいオブジェクトを作成している
const objA = {};
const objB = {};
console.log(objA == objB); // => false(異なる参照)
console.log(objA == objA); // => true(参照が一致)

比較するオペランドの型が異なり、暗黙的な型変換が行われる場合⏬

// 文字列を数値に変換してから比較
console.log(1 == "1"); // => true
// "01"を数値にすると`1`となる
console.log(1 == "01"); // => true
// 真偽値を数値に変換してから比較
console.log(0 == false); // => true
// nullの比較はfalseを返す
console.log(0 == null); // => false
// nullとundefinedの比較は常にtrueを返す
console.log(null == undefined); // => true

比較したいオペランドが null または undefined であることを判定したい場合に唯一等価演算子(==)が使われる場合⏬

  • そもそもundefinednullは大きなくくりで「値がない」ことを表現します。
  • そのため、nullまたはundifinedのどちらかが入っていれば値がないことを判定できます。
  • しかし、厳密にはundefinednullで型が異なるなどの違いがあるため、厳密等価演算子===)を使って比較すると、それぞれと比較する必要が出てきてしまいます。
  • 結果的に2回比較する必要が出てきてしまうため、等価演算子(==)を使って1回の比較で済むようにします。
const value = undefined; /* または null */
// === では2つの値と比較しないといけない
if (value === null || value === undefined) {
    console.log("valueがnullまたはundefinedである場合の処理");
}

// nullとundefinedの比較は常にtrueを返すことを利用して
console.log(null == undefined); // => true
// == では null と比較するだけでよい
if (value == null) {
    console.log("valueがnullまたはundefinedである場合の処理");
}

💡nullとundefinedの違い

undefinedとnullは大きなくくりで「値がない」ことを意味する点は共通しています。意味的な違いがあるとしたら、undefinedは「値が代入されていないため、値がない」、nullは「代入すべき値が存在しないため、値がない」という微妙な違いです。 サバイバルTypeScript - undefinedとnullの違い

  • 意図的に値がないことを示すために変数などに代入する値が null
  • プログラマーが明示的に使わなくても自然発生的に値が代入されていないことを意味するのが undefined
  • typeOf演算子を使うと、nullobject型undefinedundefined型と判定されます。
console.log(typeof undefined);
//=> "undefined"
console.log(typeof null);
//=> "object"
  • undefined変数であり、リテラルではないので、undefinedという変数を宣言できます。
  • nullリテラルであるため、nullという変数を宣言できません。

❹不等価演算子(!=)

  • 不等価演算子!=)は、2つのオペランドを比較し、等しくないならtrueを返します。
  • 不等価演算子も、等価演算子==)と同様に異なる型のオペランドを比較する際に、暗黙的な型変換をしてから比較します。
  • 暗黙的な型変換は意図しない挙動を生む可能性があるため、不等価演算子!=)を利用するべきではありません。
  • 代わりに暗黙的な型変換をしない厳密不等価演算子!==)を利用します。
// 比較するオペランドが同じ型で同じ値の場合はfalseを返す
console.log(1 != 1); // => false
console.log("str" != "str"); // => false

// 比較するオペランドが同じ型で異なる値の場合はtrueを返す
console.log("JavaScript" != "ECMAScript"); // => true
console.log(true != true);// => false

// オブジェクトは参照が一致していないならtrueを返す
const objA = {};
const objB = {};
console.log(objA != objB); // => true(オブジェクトの参照が不一致)
console.log(objA != objA); // => false(オブジェクトの参照が一致)

比較するオペランドの型が異なり、暗黙的な型変換が行われる場合⏬

// 文字列が数値に数値に変換されて、値が1で一致するためfalse
console.log(1 != "1"); // => false
// 真偽値を数値に変換してから比較。今回は、一致するのでfalse
console.log(0 != false); // => false
// nullの比較は一致しないのでtrueを返す
console.log(0 != null); // => true
// nullとundefinedの比較は常に一致するのでfalseを返す
console.log(null != undefined); // => false

参照

JSPrimer

朝会ブログ

サバイバルTypeScript - undefinedとnullの違い