JavaScript
ShoTimeDay 4

JavaScript {} === {} の出力は false

この記事は ShoTime Advent Calendar 2018 の 4 日目の記事です。

Chrome のコンソールに次のコードを打ち込んでみると、false が出力されます。

{} === {}

この理由を掴むために、JavaScript における値の型について追っていきます。
(変数の型ではありません)

プリミティブ型とオブジェクト

JavaScript においてデータ(値)はプリミティブ(primitive) ※1 かオブジェクト(object)の2つに分けられます。

プリミティブは値が不変な型で、オブジェクトは値を変更できる型です。
プリミティブには次の6種類があります。

  • 数値(Number)
  • 文字列(String)
  • 論理値(Boolean)
  • null
  • undefined
  • シンボル(Symbol)

この6種類のプリミティブ以外は、オブジェクトです。
ここでいう不変とは、変数の内容を変更できないという意味ではないので注意が必要です。

// 変数 hoge へプリミティブな値 `"Hello"` を代入
let hoge = "Hello";
// 変数 hoge へプリミティブな値 `"World"` を代入
hoge = "World";

プリミティブな値 "Hello""World" が存在し、変数 hoge は、最初に "Hello" が代入され、次に "World" が代入されています。"Hello""World" は別の文字列であるのがポイントです。

数値 00 であって、 1 ではない。というのがプリミティブです。

比較について

プリミティブはで比較するのに対して、オブジェクトは参照で比較します。そのため、オブジェクトのことを参照型と呼ぶこともあります。

let x = []; // 空の配列を変数 x へ代入(参照を代入)
let y = x; // 変数 y へ変数 x と同じ参照を代入
y[0] = 10;
console.log(x[0]); // 10
console.log(x === y); // true

上記例では、変数 y が参照しているのが [10] であることは分かりますが、変数 x も同じ [10] を参照しているのがポイントです。

タイトルの {} === {} について

{} というコードは、新しいオブジェクトリテラル ※2 を生成しています。つまり左側の {} と、右側の {} で別々の参照が作成されています。参照が別々であるということは、falsy な値であるため ※3 、false と評価し出力されます。

まとめ

非常にざっくりではありますが、JavaScript の値の型プリミティブとオブジェクトについて整理してみました。ShoTime(目標達成シート)でも Vue.js の computed や、Vuex の getters を利用しているため、この点について気をつけながらコードを書いています。

参照

注意書き

※1 プリミティブ のことを、JavaScript第6版では、 基本型 と紹介されています
※2 オブジェクトリテラルについて詳しくはこちら JavaScriptの入門書
※3 真とみなされる値を truthy、偽とみなされる値を falsy を言います