弥生研究所

人は誰しもが生きることの専門家である

【Javascript】関数とメソッドの違い

Javascript には関数という概念と、メソッドという概念が両方存在しています。

結論

結論から先に言うと、Javascript には、まず関数という概念があり、関数をオブジェクトのプロパティに代入したとき、関数はオブジェクトのメソッドになります。

関数とメソッドという全く別物の機能が存在するのではなく、オブジェクトのプロパティに代入された関数の事を便宜上メソッドと呼んでいるのです。

関数とは

まず関数の定義です。 高さと幅を与えて、面積を求める関数 getArea を定義してみます。

// 関数を定義する
function getArea(width, height) {
  return width * height;
}

// 関数を呼び出す
console.log(getArea(10, 20));

JavaScript では、関数はオブジェクトです。では、オブジェクトとは何かというと、オブジェクトはプロパティの集合です。そして、プロパティは、名前と対に値を持ちます。

単純な例として、座標、x、y を持つ「点」をオブジェクトとして考えてみましょう。

// オブジェクトを変数に代入する
const point = {
  x: 0,
  y: 0,
};

console.log(point);

ちなみに、オブジェクトは JSON 形式のデータです。JSON は今でこそ一般的なデータフォーマットとして利用されていますが、JSONJavaScript Object Notation の略語であるように、元々は Javascript のオブジェクトを表記するためのフォーマットです。

関数はオブジェクトですから、上記の関数 getArea の定義と、変数 point の定義は、どちらもオブジェクトになります。関数はオブジェクトであり、オブジェクトはプロパティの集合であり、プロパティは名前と値を対に持ちますから、関数は名前と値の対を持っていることになります。ここで、関数 getArea は「getArea」という名前と、「関数本体の処理」という値を持っています。

メソッドとは

次にメソッドの定義です。 関数をオブジェクトのプロパティに代入したとき、関数はオブジェクトのメソッドになります。

先ほどの「点」のオブジェクトに、高さと幅のプロパティを持たせて「矩形」とし、面積を求める関数をメソッドにしてみましょう。簡単です、関数をプロパティに代入するだけです。

function getAreaFunction() {
  return this.width * this.height;
}

const rectangle = {
  x: 0,
  y: 0,
  width: 10,
  height: 20,
  getAreaMethod: getAreaFunction,
};

// メソッドを呼び出す
console.log(rectangle.getAreaMethod());

よりスマートに書くと以下のようになります。

const rectangle = {
  x: 0,
  y: 0,
  width: 10,
  height: 20,
  getArea() {
    return this.width * this.height;
  },
};

console.log(rectangle.getArea());

さて、関数はオブジェクトなので、変数やプロパティに代入し放題です。したがって、Javascript においては、関数そのものを指し示す場合と、関数を呼び出す場合は、明確に差があることに注意が必要です。

function helloWorld() {
  return 'Hello World';
}

// 関数そのものをログに出力する
console.log(helloWorld);

// 関数を呼び出し、関数が返した値をログに出力する
console.log(helloWorld());

ところで、オブジェクトのもっとも単純な定義は、空のオブジェクトの定義です。 空のオブジェクトは以下のように定義できます。

const emptyObject = {};

Javascript では、{} は if 文や for 文などで使う、文ブロックの意味のほかに、オブジェクトの定義という意味を持ちます。 特に、{} だけでは文ブロックなのか、オブジェクトなのかが判断できないため、前後の文脈から判断する必要があります。

// オブジェクトにはプロパティを記述する(文は記述できない)
const testObject = {
  width: 10,
  height: 20,
};

// 文ブロックには文を記述する(プロパティを記述できない)
{
  const width = 10;
  const height = 20;
  console.log(width * height);
}

以上です。

f:id:yayoi-tech:20190616172928p:plain