不,暂时不会 :(
从CoffeeScript FAQ中得知:
问: 你会加入依赖于平台的功能X吗?
答: 不会,根据政策,不允许使用特定于实现的特性。你在CoffeeScript中编写的所有内容都应该在任何当前JavaScript实现上支持和运行(实际上,这意味着最低公共分母是IE6)。因此,以下功能将不会被实现: getters & setters, yield.
一些关于getter & setter语法的GitHub问题: #64, #451, #1165 (最后一个问题有一些好的讨论)。
我个人认为,现在 defineProperty成为ECMAScript标准的一部分,为CoffeeScript添加getter和setter字面语法将是一个不错的可选功能。在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
p.fullName = 'Space Monkey'
console.log p.lastName
或者,也许创建两种不同的方法:
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
;)),就像Jason提议的那样。也许可以将其包装在一个小函数中:
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
rectangle.width = 5
console.log rectangle.area