JavaScript | 第12章「オブジェクトに関する扱い方」

javascrpit JavaScript
スポンサーリンク

“オブジェクトに関する扱い方”(Working with objects)をわかりやすく解説する。理解を助けるために、例を交えつつ進める。


全体像:オブジェクトとは何か?

  • JavaScript における オブジェクト (object) は、「名前(キー)と値の組み合わせ(プロパティの集まり)」として表されるデータ構造。
  • プロパティの値には 普通の値(文字列、数値、真偽値など)だけでなく 関数 も入れられる。その場合、そのプロパティは「メソッド (method)」と呼ばれる。
  • オブジェクトは “箱” のようなもので、中に複数のプロパティ(名前付きの値)を持てると考えればいい。

主なトピックとポイント

項目内容の概要
オブジェクトとプロパティオブジェクトにプロパティを持たせる方法、読み書きの仕方
オブジェクトの生成方法リテラル (literal)、コンストラクタ関数、Object.create など
メソッドの定義プロパティとして関数を使う、this の扱い
ゲッター/セッタープロパティアクセス時に自動処理を挟む方法
プロパティの削除delete 演算子でプロパティを消す方法
オブジェクト比較同じオブジェクトかどうか、あるいは別々かどうかの判定

以下、それぞれを初心者向けに掘り下げる。

オブジェクトとプロパティ:基本の使い方

オブジェクトリテラルでの生成

最もよく使うパターン。 { … } を使って直接書く。

const person = {
  name: "Alice",
  age: 30,
  greet: function() {
    console.log("Hello, I'm " + this.name);
  }
};

// ES6 以降はメソッド定義を省略形で書ける
const person2 = {
  name: "Bob",
  age: 25,
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
};
JavaScript
  • name, age, greet がプロパティ(greet はメソッド)
  • this はそのオブジェクト自身を指す(後述)
  • オブジェクトの中にオブジェクトを持たせることもできる:
const car = {
  model: "Toyota",
  engine: {
    cylinders: 4,
    size: 2.0
  }
};
JavaScript

このような書き方を「オブジェクトリテラル (object literal)」または「オブジェクト初期化子 (object initializer)」という。

プロパティの読み書き:ドット表記 vs 角かっこ表記

ドット表記(.

person.name        // "Alice"
person.age = 31;   // age プロパティを更新
JavaScript

ただし、プロパティ名が変数や動的な値で決まる場合、ドット表記は使えない。

角かっこ表記([]

person["name"]     // "Alice"
const key = "age";
person[key] = 35;  // このように変数 key を使ってアクセス可能
JavaScript

この方式だと、プロパティ名が数値や文字列として動的に決まる時に便利。
また、プロパティ名に空白があったり記号が含まれていたりするときも [] 表記を使わないといけない。

入れ子アクセス

car.engine.size;            // 2.0
car["engine"]["cylinders"]; // 4
JavaScript

オブジェクトの生成方法(リテラル以外)

コンストラクタ関数を使う方法

オブジェクトのテンプレート(設計図)を関数で定義して、new を使って複数のオブジェクトを作る方法。

function Person(name, age) {
  this.name = name;
  this.age = age;

  this.sayHi = function() {
    console.log(`Hi, I'm ${this.name}`);
  };
}

const alice = new Person("Alice", 30);
const bob = new Person("Bob", 25);

alice.sayHi();  // Hi, I'm Alice
JavaScript
  • this は新しく作られるオブジェクトを指す
  • new Person(...) によって空のオブジェクトが作られ、その this にプロパティを付与して、最終的にそのオブジェクトが返る
  • ただし、この方法だと sayHi のようなメソッドが各インスタンス毎に別々に作られる(余分なメモリを使うことがある)という欠点もある

Object.create を使う方法

プロトタイプ(親オブジェクト)を指定して新しいオブジェクトを作る方法。これによって、プロトタイプを共有できる。

const proto = {
  describe() {
    console.log(`name: ${this.name}`);
  }
};

const obj = Object.create(proto);
obj.name = "Charlie";
obj.describe();  // name: Charlie
JavaScript

この方式だと、proto のメソッドやプロパティを新しいオブジェクト obj が継承できる。

メソッドと this

  • オブジェクトのプロパティに関数を入れたものを「メソッド」と呼ぶ。
  • メソッド内で使われる this は、実行時の呼び出し元オブジェクトを指す。
const user = {
  name: "Dana",
  sayName() {
    console.log(this.name);
  }
};
user.sayName();  // "Dana"
JavaScript
  • ただし、関数参照を変数に取り出してから呼ぶと this が変わるので注意。

ゲッター (getter)/セッター (setter)

特定のプロパティにアクセスしたとき、自動的に関数を実行したい場合に使える。

const obj = {
  _value: 10,  // 実体のプロパティ(慣習でアンダースコアをつけることもある)
  get value() {
    console.log("getter が呼ばれた");
    return this._value;
  },
  set value(val) {
    console.log("setter が呼ばれた");
    this._value = val;
  }
};

console.log(obj.value);  // getter が呼ばれた → 10
obj.value = 20;          // setter が呼ばれた
console.log(obj.value);  // getter が呼ばれた → 20
JavaScript
  • get xxx():プロパティを取得しようとしたときに呼ばれる
  • set xxx(val):プロパティに書き込もうとしたときに呼ばれる
  • 見た目は通常のプロパティアクセスだけど、裏で関数が走るようにできる機能

プロパティの削除

オブジェクトからプロパティを削除したいときは delete を使う。

const obj = {
  a: 1,
  b: 2
};

delete obj.a;
console.log(obj);  // { b: 2 }
JavaScript

ただし、すべてのプロパティが削除できるわけじゃない(プロパティの設定方法によっては削除不可能なものもある)という注意もある。

オブジェクトの比較

単純に ===== で比べると、「同一のオブジェクトか?」が基準になる。

const x = { value: 1 };
const y = { value: 1 };
const z = x;

console.log(x === y);  // false(中身は同じでも別のオブジェクト)
console.log(x === z);  // true(z は x と同じオブジェクトを参照している)
JavaScript

さらに、Object.is() というメソッドを使うと、NaN の比較や +0-0 の区別などもできるようになる。

付け足し:プロトタイプと継承(深い内容)

MDN の本章ではプロトタイプ(プロトタイプチェーン)や継承 (inherence) の説明もされてるけど、これは少し中級寄りの話。
簡単に言うと、オブジェクトには「親オブジェクト(プロトタイプ)」を持てて、そこからプロパティやメソッドを引き継ぐことができる仕組み。
(将来的にクラス構文 class を使う方が扱いやすい場合もある)

タイトルとURLをコピーしました