如何监控Javascript对象上新属性的设置



我怎么能得到一个回调每当新的属性设置在Javascript对象..?
例如,我不知道要设置哪些属性,但想要为设置的任何属性进行回调。

我想要的是

var obj = {};
obj.a = "something"; // triggers callback function
function callback(obj,key,val) {
    console.log(key + " was set to " + val + " on ", obj);
}

这可能吗?

您可以使用新的defineProperty:

function onChange(propertyName, newValue){
...
}
var o = {};
Object.defineProperty(o, "propertyName", { 
 get: function() {return pValue; },
 set: function(newValue) { onChange("propertyName",newValue); pValue = newValue;}});

但这取决于你需要支持的浏览器版本

编辑:在Jsfiddle上添加片段,在IE10中工作。http://jsfiddle.net/r2wbR/

最好使用setter函数,不需要getter,

var obj = {};
setKey(obj, 'a', "something"); // triggers callback function
function setKey(obj, key, val){
    obj[key] = val;
    callback(obj, key, val);
}
function callback(obj, key, val) {
    console.log(key + " was set to " + val + " on ", obj);
}

尽量通用,不要对所有键都使用不同的函数

在这里试试

最好是有setter和getter方法。但是根据你之前的实现,你仍然可以改变你的对象属性而不使用setter和getter。因此,应该将敏感变量设为private。下面是一个简短的例子:

var Person = (function() {
    function Person() {};
    var _name;
    Person.prototype.setName = function(name) {
        _name = name;
    };
    Person.prototype.getName = function() {
        return _name;
    };
    return Person;
})();
var john = new Person();
john.getName();
// => undefined
john.setName("John");
john.getName();
// => "John"
john._name;
// => undefined
john._name = "NOT John";
john.getName();
// => "John"

不幸的是,JavaScript不会让您知道属性何时被更改。很多次我都希望它能这样,但由于它不能,我不得不找到一个变通的办法。不是直接设置属性,而是通过触发回调函数的setter方法来设置它(也可能使用getter方法来访问属性),如下所示:

function callback(obj,key,val) {
    console.log(key + " was set to " + val + " on ", obj);
}
var obj = {};
obj.setA=function(value){
    obj.a=value;
    callback(obj,'a',value);// triggers callback function
}
obj.getA=function(){
    return obj.a;
}
obj.setA("something");

jsFiddle: http://jsfiddle.net/jdwire/v8sJt/

EDIT:如果你想完全避免在没有回调的情况下改变属性,另一个选择:

function callback(obj,key,val) {
    console.log(key + " was set to " + val + " on ", obj);
}
var obj={};
(function(){
   var a=null;
   obj.setA=function(value){
       a=value;
       callback(obj,'a',value);// triggers callback function
   }
   obj.getA=function(){
       return a;
   }
})()
console.log("a is "+obj.getA());// a is null
obj.setA("something"); // Set a to something
console.log("a is now "+obj.getA()); // a is now something
obj.a="something else"; // Set obj.a to something else to show how a is only accessible through setA
console.log("a is still "+obj.getA()); // a is still something

jsFiddle: http://jsfiddle.net/jdwire/wwaL2/

最新更新