高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

幫你的類別增加功能

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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啦,這樣一來,你就可以寫出這樣的程式:

1
2
3
4
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一份過來? 還是早就已經有了.. :)

Comments