Non, pas pour le moment :(
De la FAQ sur CoffeeScript :
Q : Allez-vous ajouter la fonctionnalité X lorsque cette dernière dépend d'une plateforme ?
R : Non, les fonctionnalités spécifiques à une implémentation ne sont pas autorisées en tant que politique. Tout ce que vous écrivez en CoffeeScript doit être pris en charge et exécutable sur n'importe quelle implémentation JavaScript actuelle (en pratique, cela signifie que le plus petit dénominateur commun est IE6). Ainsi, les fonctionnalités suivantes ne seront pas implémentées : getters & setters, yield.
Quelques problèmes sur GitHub concernant la syntaxe getter & setter : #64 , #451 , #1165 (il y a une bonne discussion dans le dernier).
Je pense personnellement qu'avoir une syntaxe littérale getter & setter serait une fonctionnalité intéressante pour CoffeeScript maintenant que defineProperty
es fait partie de la norme ECMAScript . La nécessité des getters & setters en JavaScript peut être discutable, mais vous n'êtes pas obligé de les utiliser simplement parce qu'ils existent.
Quoi qu'il en soit, comme vous l'avez remarqué, il n'est pas très difficile d'implémenter une fonction d'enveloppe pratique qui appelle Object.defineProperty
pour les déclarations de classes. Personnellement, j'utiliserais l'approche suggérée dans aquí :
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
Ou alors, créez deux méthodes différentes :
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 ' '
Pour les objets simples, vous pouvez simplement utiliser Object.defineProperty
(ou Object.defineProperties
;) ) sur l'objet lui-même comme Jason a proposé . On pourrait peut-être l'envelopper dans une petite fonction :
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