ES6 Method Definition

以前在產生 function 時,一定不外乎是 function declaration:

function foo() { return; }

或是 function expression:

var foo = function () { return; }

不過在 ES6 有一種新的特殊的語法可以使用,叫做 method definition,顧名思義,這個新的語法是專門用在產生物件的 method 上用的,所以嚴格說來不是用來做 function 的,然後也因此很特別的不需要使用到 function 這個關鍵字,基本的用法通常會在 class syntax 中使用:

class foo {
  constructor() {
    //blah
  }

  fooMeth() {
    //blah
  }
}

在上面這段程式碼中,constructorfooMeth都是 method definition,其實就很接近以前的 prototype method,但是大幅簡化了語法,而除了這樣使用,還可以配合getset讓它變成 accessor function:

class foo {
  get bar() {
    return this._bar;      
  }
  set bar(v) {
    this._bar = v + this._bar;
  }
}

Accessor 其實在 ES5 就已經有了,不過因為一直被 IE 卡著所以不太有人用,而且寫起來實在也麻煩很多,以前是要用defineProperty才能定義 accessor:

Object.defineProperty(foo.prototype, 'bar', {
  get: function () {
    return this._bar;
  },
  set: function (v) {
    this._bar = v + this._bar;
  }
});

當然除了比較麻煩外,還有一個問題就是defineProperty只能用在實體物件上,所以上面的 class 範例,要做出一樣效果就要在 prototype 上使用,實在不直觀,加上defineProperty其他功能真的是很少看到使用需求,新的語法這樣設計真的是很不錯,不過看到defineProperty要在實體物件上用,就會讓人反過來想,method definition 可以不用在 class 上,而是用在普通物件上嗎?事實上是可以的,ES6 的物件語法多了簡化的寫法,其中一個就是支援 method definition,所以可以這樣寫:

var object = {
  value: 42,
  toString() {
    return this.value;
  }
};