No, not for now :(
From the CoffeeScript FAQ:
Q: Will you add feature X where feature X depends on a platform?
A: No, implementation-specific features are not allowed as a policy. Everything that you write in CoffeeScript should be supported and runnable on any current JavaScript implementation (in practice, this means the lowest common denominator is IE6). Thus, features such as the following will not be implemented: getters & setters, yield.
Some GitHub issues about getter & setter syntax: #64, #451, #1165 (there is some nice discussion in the last one).
I personally think that having getter & setter literal syntax would be a nice opt-in feature for CoffeeScript now that defineProperty
is part of the ECMAScript standard. The need for getters & setters in JavaScript can be questionable, but you're not forced to use them just because they exist.
Anyway, as you noticed, it's not that hard to implement a convenient wrapper function that calls Object.defineProperty
for class declarations. I personally would use the approach suggested in here:
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
Or, maybe create two different methods:
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 ' '
For plain objects you can just use Object.defineProperty
(or Object.defineProperties
;) ) on the object itself as Jason proposed. Maybe wrap that in a little function:
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