JavaScript | ES6+ 文法:オブジェクト拡張 – メソッド定義省略

JavaScript JavaScript
スポンサーリンク

メソッド定義省略とは何か

オブジェクトの「メソッド定義省略」は、ES6 から入った“関数っぽいプロパティ”を短く書くための記法です。

従来はこう書いていました。

const user = {
  name: "Alice",
  greet: function () {
    console.log("Hello, " + this.name);
  }
};
JavaScript

メソッド定義省略を使うと、function を省いてこう書けます。

const user = {
  name: "Alice",
  greet() {
    console.log("Hello, " + this.name);
  }
};

user.greet(); // "Hello, Alice"
JavaScript

ここが重要です:
見た目は短くなっていますが、意味は「greet: function () { ... } と同じ」です。
this の動きも、従来のメソッドと同じと考えて大丈夫です(あとで詳しく触れます)。


基本構文と従来構文の比較

旧スタイル(ES5 まで)

const calculator = {
  value: 0,
  add: function (n) {
    this.value += n;
  },
  reset: function () {
    this.value = 0;
  }
};
JavaScript

新スタイル(メソッド定義省略)

const calculator = {
  value: 0,
  add(n) {
    this.value += n;
  },
  reset() {
    this.value = 0;
  }
};
JavaScript

どちらもやっていることは同じですが、新スタイルの方が

  • 何が「メソッド(動き)」で
  • 何が「プロパティ(データ)」

かをパッと見で区別しやすくなります。

ここが重要です:
名前(引数) { … } と書かれていたら、それは 名前: function(引数) { … } の省略形」
と頭に入れておけば十分です。


メソッド定義省略のルールと書き方のコツ

ルール1:オブジェクトリテラルの「中」でだけ使える

メソッド定義省略は、「オブジェクトを {} で書いているところ」でしか使えません。

// OK:オブジェクトリテラルの中
const obj = {
  foo() {
    console.log("foo");
  }
};

// NG:単体の関数定義では使えない
// function bar() {} は OK だが、
// bar() {} という書き方はできない
JavaScript

クラスの中でも似たような書き方ができますが、それは「クラスのメソッド定義」としてのルールです。
オブジェクトリテラルの話としては、「中でしか使えない」と覚えておけば大丈夫です。

ルール2:this の動きは「普通のメソッド」と同じ

これ、かなり大事なポイントです。

const counter = {
  value: 0,
  up() {
    this.value++;
  }
};

counter.up();
console.log(counter.value); // 1
JavaScript

up() メソッドの中で this.value と書くと、
これは counter.value を指します(counter 経由で呼ばれたとき)。

つまり、メソッド定義省略は

  • アロー関数ではない
  • this の挙動は従来のメソッド(function)と同じ

ここが重要です:
「オブジェクトのメソッドにアロー関数を使うと this の挙動が変わって危険だが、メソッド定義省略なら従来どおり安全」
という整理をしておくと混乱しにくくなります。


アロー関数との違い(ここをしっかり理解する)

初心者が一番混乱しやすいのが、「メソッド定義省略」と「アロー関数」の違いです。

アロー関数でメソッドを書くとどうなるか

const counter = {
  value: 0,
  up: () => {
    console.log(this); // 期待したものではない
    // this.value は undefined になる可能性が高い
  }
};
JavaScript

アロー関数は「自分の this を持たない」ので、
メソッドとして this を使いたい場面には向きません。

メソッド定義省略なら従来どおり

const counter = {
  value: 0,
  up() {
    this.value++;
  }
};

counter.up();
console.log(counter.value); // 1
JavaScript

ここが重要です:
オブジェクトの「メソッド」として定義するなら、基本はメソッド定義省略(または function)を使う。
アロー関数は「this に依存しない小さな処理」に使う。

これをルールとして持っておくと、this 周りのバグをかなり減らせます。


実務でよく使うパターン

データと振る舞いをひとまとめにする

const user = {
  name: "Alice",
  loginCount: 0,

  login() {
    this.loginCount++;
    console.log(`${this.name} logged in (${this.loginCount})`);
  },

  rename(newName) {
    this.name = newName;
  }
};

user.login();      // Alice logged in (1)
user.rename("Bob");
user.login();      // Bob logged in (2)
JavaScript

「何ができて、どう変わるか」が、オブジェクトの中にコンパクトにまとまります。
メソッド定義省略を使うと、コードの“形”から「ここはメソッドだな」とすぐ分かります。

ユーティリティオブジェクトを作る

const mathUtil = {
  // x, y の距離を求める
  distance(x, y) {
    return Math.sqrt(x * x + y * y);
  },

  // 度をラジアンに変換
  toRad(deg) {
    return (deg * Math.PI) / 180;
  }
};

console.log(mathUtil.distance(3, 4)); // 5
console.log(mathUtil.toRad(180));     // 3.1415...
JavaScript

こういった「関数をまとめたオブジェクト」にも、メソッド定義省略はよく使われます。
distance: function () {} より distance() {} の方が、読みやすく、見た目もすっきりします。

イベントハンドラをオブジェクトでまとめる

const handlers = {
  click() {
    console.log("clicked");
  },
  mouseover() {
    console.log("mouse over");
  }
};

// 例:DOM イベントに割り当てるとき
// element.addEventListener("click", handlers.click);
// element.addEventListener("mouseover", handlers.mouseover);
JavaScript

よくある勘違い・落とし穴(重要ポイントの深掘り)

「見た目が短い=アロー関数」と思い込まない

const obj = {
  foo() {},      // ← これは「省略された function」
  bar: () => {}  // ← これはアロー関数
};
JavaScript

foo() の中の thisobj を指しますが、
bar の中の thisobj ではありません(外側の this に依存)。

ここが重要です:
かっこの前に : があるかどうかで、「普通のメソッド」か「アロー関数」かを見分ける

  • foo() {} → メソッド定義省略(function と同じ this
  • foo: () => {} → アロー関数(this を持たない)

メソッドを「変数に取り出して呼ぶ」と this が変わる

これは省略記法に限らず、従来からある JavaScript のルールですが、
メソッドを別変数に保存して呼ぶと this が変わります。

const user = {
  name: "Alice",
  greet() {
    console.log(this.name);
  }
};

user.greet(); // "Alice"

const fn = user.greet;
fn(); // this が user ではなくなるので、undefined になることが多い
JavaScript

対策としては、呼び出し側で user.greet() の形を保つか、
bindthis を固定するなどの方法があります。
これは「メソッド定義省略だから」ではなく、「普通のメソッドと同じ注意点」です。


例題で理解を固める

// 1) 旧スタイル vs メソッド定義省略
const objOld = {
  x: 1,
  getX: function () {
    return this.x;
  }
};

const objNew = {
  x: 1,
  getX() {
    return this.x;
  }
};

console.log(objOld.getX()); // 1
console.log(objNew.getX()); // 1


// 2) データ+メソッドをまとめたオブジェクト
const bankAccount = {
  balance: 0,

  deposit(amount) {
    this.balance += amount;
  },

  withdraw(amount) {
    if (this.balance >= amount) {
      this.balance -= amount;
      return true;
    }
    return false;
  }
};

bankAccount.deposit(1000);
console.log(bankAccount.balance); // 1000
bankAccount.withdraw(300);
console.log(bankAccount.balance); // 700


// 3) ユーティリティオブジェクト
const stringUtil = {
  toUpper(str) {
    return str.toUpperCase();
  },
  trimAndLower(str) {
    return str.trim().toLowerCase();
  }
};

console.log(stringUtil.toUpper("abc"));        // "ABC"
console.log(stringUtil.trimAndLower("  HeLLo ")); // "hello"


// 4) アロー関数と省略記法の挙動の違い
const obj = {
  value: 42,
  normal() {
    console.log("normal this.value:", this.value);
  },
  arrow: () => {
    console.log("arrow this.value:", this && this.value);
  }
};

obj.normal(); // normal this.value: 42
obj.arrow();  // arrow this.value: undefined(多くのケースで)
JavaScript

まとめ

メソッド定義省略の核心は、
「オブジェクトリテラルの中で name: function (...) { ... }name(...) { ... } と短く書ける」 ことです。

これにより、

  • データとメソッドがコンパクトにまとまり
  • 「ここはメソッドだ」という意図が構文からすぐ読み取れ
  • this の挙動は従来のメソッドと同じなので、アロー関数のような落とし穴を避けやすくなる

というメリットがあります。

ポイントは、

  • 省略されているだけで中身は function だという理解
  • アロー関数とは this の挙動がまったく違うこと
  • オブジェクトの「動き(振る舞い)」をまとめたいときに、メソッド定義省略を使う

このあたりを意識していれば、初心者でも ES6 のオブジェクト拡張を自然に使いこなせるようになります。

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