幫你的類別增加功能

CoffeeScript 很有趣也很好寫,雖然它提供了許多的語法糖衣(Syntactic sugar),讓你用短短的幾行程式碼就能換來原來你在 JavaScript 要做的事。但說白了它本質上還是 JavaScript,JavaScript 做不到的事,用 CoffeeScript 一樣也做不到。

不過有些很常做的工作,例字串變換大小寫,雖然 JavaScript 的字串本身已經有 toUpperCase() 以及 toLowerCase() 的功能,但我已經寫習慣 Ruby 的 upcasedowncase,要記那麼多個名字實在很辛苦,每次都得去 google 一才下知道要怎麼寫;又如果我想把某個字串重複 10 次,在 Ruby 有 * 可以用,但在 JavaScript 似乎沒有原生的 function 可以用.. 有沒有辦法也自己做一些讓自己順手的小工具,讓自己寫程式的時候順利一些呢?

如果你曾經寫過 Python 或 Ruby,就會知道其實它們的類別裡的方法是可以很簡單的被打開再新增或覆寫(open class),在 JavaScript/CoffeeScript 也有類似的做法,在 CoffeeScript 就是使用 :: 來幫原來已經定義好的類別再增加功能:

String::repeat = (n) ->
  Array(n + 1).join @

String::downcase = ->
  @toLowerCase()

String::upcase = ->
  @toUpperCase()

String::find = (str) ->
  @indexOf str

String::has = (str) ->
  (@indexOf str) > 0

編譯出來的 JavaScript 長這樣:

String.prototype.repeat = function(n) {
  return Array(n + 1).join(this);
};
String.prototype.downcase = function() {
  return this.toLowerCase();
};
String.prototype.upcase = function() {
  return this.toUpperCase();
};
String.prototype.find = function(str) {
  return this.indexOf(str);
};
String.prototype.has = function(str) {
  return (this.indexOf(str)) > 0;
};

其實那個 ::,用的就是 prototype 啦,這樣一來,你就可以寫出這樣的程式:

console.log "a".repeat 10 # aaaaaaaaaa
console.log "this is a book".upper() # THIS IS A BOOK
console.log "this is a book".find "book" # 10
console.log "this is a book".has "book" # true

程式看起來乾淨多了,也習慣多了,心情也會比較好一些。

PS:不知道會不會有善心人士會把 Python 或 Ruby 一些好用的功能也 port 一份過來?還是早就已經有了.. :)