いいえ、今のところではありません:(
CoffeeScript FAQから:
Q: プラットフォームに依存する機能 X を追加する予定はありますか?
A: いいえ、実装固有の機能はポリシーとして許可されていません。CoffeeScript で記述したものはすべて、現在の JavaScript 実装でサポートされ、実行可能である必要があります (実際には、これは最小公分母が IE6 であることを意味します)。したがって、ゲッターとセッター、yield などの機能は実装されません。
ゲッターとセッターの構文に関するいくつかの GitHub の問題: #64、#451、#1165 (最後のものでいくつかの良い議論があります)。
defineProperty
個人的には、getter と setter のリテラル構文を持つことは、ECMAScript 標準の一部となった CoffeeScript の優れたオプトイン機能になると思います。JavaScript での getter と setter の必要性は疑わしい場合がありますが、それらが存在するという理由だけでそれらを使用する必要はありません。
Object.defineProperty
とにかく、お気づきのように、クラス宣言を呼び出す便利なラッパー関数を実装するのはそれほど難しくありません。個人的には、ここで提案されているアプローチを使用します。
Function::property = (prop, desc) ->
Object.defineProperty @prototype, prop, desc
class Person
constructor: (@firstName, @lastName) ->
@property 'fullName',
get: -> "#{@firstName} #{@lastName}"
set: (name) -> [@firstName, @lastName] = name.split ' '
p = new Person 'Robert', 'Paulson'
console.log p.fullName # Robert Paulson
p.fullName = 'Space Monkey'
console.log p.lastName # Monkey
または、2 つの異なるメソッドを作成することもできます。
Function::getter = (prop, get) ->
Object.defineProperty @prototype, prop, {get, configurable: yes}
Function::setter = (prop, set) ->
Object.defineProperty @prototype, prop, {set, configurable: yes}
class Person
constructor: (@firstName, @lastName) ->
@getter 'fullName', -> "#{@firstName} #{@lastName}"
@setter 'fullName', (name) -> [@firstName, @lastName] = name.split ' '
単純なオブジェクトの場合、ジェイソンが提案しObject.defineProperty
たように、オブジェクト自体に(またはObject.defineProperties
;) ) を使用できます。多分それを小さな関数でラップします:
objectWithProperties = (obj) ->
if obj.properties
Object.defineProperties obj, obj.properties
delete obj.properties
obj
rectangle = objectWithProperties
width: 4
height: 3
properties:
area:
get: -> @width * @height
console.log rectangle.area # 12
rectangle.width = 5
console.log rectangle.area # 15