Javascript Object.defineProperty установить метод триггера на изменение свойства
Возьмем следующий (coffeescript) пример класса Person со свойством details, которое, в свою очередь, имеет свои собственные свойства:
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
Очевидно, что если бы я просто определил имя и возраст как свойства класса Person, я мог бы избежать этой проблемы, но это всего лишь пример.
Есть ли какой-нибудь простой способ заставить мой метод set() срабатывать при изменении его свойств?
1 ответ
На самом деле, нет. По крайней мере, не просто.
p
это совершенно другой объект, чем p.details
, Изменение p.details
ничего не меняет p
совсем. Так что не получу сообщение.
Что вам нужно сделать, это установить некоторый код, который заставляет объект details отправлять сообщение своему родителю при изменении его собственных свойств. Что также означает, что он должен знать, кто его родитель.
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/
Но, честно говоря, это немного безумие. Вы уверены, что это то, что вам нужно сделать? Может быть, вам следует пересмотреть свой подход.