Ответ 1
Более широко поддерживаемый подход может быть Object.defineProperty. defineProperty может использоваться, чтобы иметь некоторый контроль над определенным свойством объекта, например:
var o = { prop: '' };
Object.defineProperty(o, 'prop', {
get: function() { return this.value; },
set: function(newValue) {
// a certain property is being changed
alert('is changed');
this.value = newValue;
}
});
o.prop = 'Johnson';
В приведенном выше примере показано, как вы можете использовать defineProperty, а при изменении параметра o o определяется назначенный набор (set).
В нижней части этого reference вы можете видеть, что даже IE-8 поддерживает его, но только при определенных условиях (IE8 поддерживает только объект Object.defineProperty для использования на узлах DOM).
Но будьте осторожны при использовании, потому что это также присваивает свойство оконному объекту из-за отсутствия этого:
var o = { b:''};
Object.defineProperty(o, 'b', {
get: function() { return value; },
set: function(newValue) { value = newValue; },
});
o.b = 'abc';
console.log(window.value); // 'abc'
Способ отслеживания старого значения свойства
Это больше соответствует вашему запросу:
var o = { prop: '' };
Object.defineProperty(o, 'prop', {
get: function() { return this.propValue; },
set: function(newValue) {
// an certain property is being changed
console.log('old-value: ',this['oldprop']);
console.log('new-value: ',newValue);
this.propValue = newValue;
this['oldprop'] = this.propValue;
}
});
o['prop'] = 'joseph';
console.log(o);
o['prop'] = 'jack';
console.log(o);
o['prop'] = 'john';
console.log(o);
Наблюдать весь объект с помощью Object.defineProperty
Кроме того, вы можете создать функцию, которая отслеживает весь объект и изменяется ли какое-либо свойство:
function observeObject(obj){
var keys = Object.keys(obj);
for(var k=0; k < keys.length; k++){
var key = keys[k];
(function(key){
var keyName = key+'value';
var oldKeyName = 'old'+key+'value';
obj[oldKeyName] = obj[key];
Object.defineProperty(obj, key, {
get: function() { return this[keyName]; },
set: function(newValue) {
console.log('old-value: ',this[oldKeyName]);
console.log('new-value: ',newValue);
this[keyName] = newValue;
this[oldKeyName] = this[keyName];
}
});
})(key);
}
}
var person = { name : 'jack', age: 26 };
observeObject(person);
person.name = 'john';
person['age'] = 27;