Object.observe -- 并非所有主要浏览器都支持,我可以使用什么作为替代方案?
Object.observe -- not supported by all major browsers, what can I use as an alternative?
我有一个在 Chrome 中工作的函数,它会在名为 finishedLoading 的变量更改值时打印到控制台。
Object.observe(finishedLoading, function(id, oldval, newval) {
console.log('finished loading' + id + ' went from ' + oldval + ' to ' + newval);
}
这不适用于许多其他现代浏览器(例如 firefox、safari)。有没有我可以使用的替代方案会得到更好的支持?谢谢!
更广泛支持的方法可能是 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 的 prop改变了定义的 setter (set) 被调用。
在这个 reference 的底部你可以看到即使 IE-8 也支持它,但只是在某些条件下(IE8 只支持 Object.defineProperty 在 DOM 节点上使用) .
但是在使用它时要小心,因为这会将 属性 分配给 window 对象,因为缺少 this:
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;
我有一个在 Chrome 中工作的函数,它会在名为 finishedLoading 的变量更改值时打印到控制台。
Object.observe(finishedLoading, function(id, oldval, newval) {
console.log('finished loading' + id + ' went from ' + oldval + ' to ' + newval);
}
这不适用于许多其他现代浏览器(例如 firefox、safari)。有没有我可以使用的替代方案会得到更好的支持?谢谢!
更广泛支持的方法可能是 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 的 prop改变了定义的 setter (set) 被调用。
在这个 reference 的底部你可以看到即使 IE-8 也支持它,但只是在某些条件下(IE8 只支持 Object.defineProperty 在 DOM 节点上使用) .
但是在使用它时要小心,因为这会将 属性 分配给 window 对象,因为缺少 this:
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;