使用带有详细信息属性的Person类的以下(coffeescript)示例,该属性又具有自己的属性:
class Person
constructor: ->
details =
name: ''
age: 0
Object.defineProperty this, 'details',
enumerable: yes
get: => details
set: (value) =>
console.log 'set details:', value
details = value
p = new Person
# does NOT trigger details set()
p.details.name = 'Simon'
# DOES trigger details set(), but takes a bit of effort...
details = p.details
details.name = 'Someone else'
p.details = details
显然,如果我只是将name和age定义为Person类的属性,我可以避免这个问题,但这只是一个例子。
有没有简单的方法可以让我的详细信息set()方法在其属性发生变化时触发?
答案 0 :(得分:2)
不是真的。至少不是简单的。
p
与p.details
完全不同。修改p.details
根本不会改变p
的任何内容。所以它不会得到消息。
您需要做的是安装一些代码,使详细信息对象在其自身属性发生更改时向其父级发送消息。这也意味着它需要知道它的父母是什么。
class Person
constructor: ->
details =
name: ''
age: 0
Object.defineProperty this, 'details',
enumerable: yes
get: -> details
set: (value) ->
console.log 'set details:', value
details = value
# set parent object to tell when something changes
value._parent = this
# create a name setter, which tells it's parent when it changes.
Object.defineProperty details, 'name',
enumerable: yes
get: -> @_name
set: (value) ->
@_parent.didUpdateDetails()
# trigger setter to install hook
@details = details
didUpdateDetails: ->
console.log 'Updated details!'
p = new Person
p.details.name = 'Alex'
# logs: "Updated details!"
是的,这确实有效:http://jsfiddle.net/PkyaU/1/
但说实话,这有点疯狂。你确定这是你需要做的吗?也许你应该重新考虑你的方法。