在对象上设置属性时调用函数

我真的不知道如何解释这个,但我会告诉你代码,并告诉你我想达到什么目的。

比方说,我做一个快速的对象:

var test = {}; 

然后我给它设置一个属性:(我坚持语法,它不能使用任何函数作为setter)

 test.hello = 'world'; 

很简单,呃? 现在我想添加一个函数,该函数会在每次设置新属性时调用。 喜欢这个:

 var test = { newPropertyHasBeenSet: function(name){ console.log(name + 'has been set.'); } }; test.hello = 'world'; // Now newPropertyHasBeenSet gets called with 'hello' as an argument. // hello has been set. 

我不知道这是否有可能,但那将是相当惊人的。 任何人都有如何实现的想法?

编辑:我也想能够做同样的属性得到(所以test.hello会调用get('hello')例如)。

编辑2: 这是服务器端javascript使用node.js。

非常感谢,祝你有美好的一天!

在chrome中尝试这个例子(正如前面的评论中提到的那样,它使用ES6代理 ):

 var p = Proxy.create({ get: function(proxy, name) { console.log('read request to ' + name + ' property'); if (name=="test_test") return 1234; else return "Meh"; }, set: function(proxy, name, value) { console.log('write request to ' + name + ' property with ' + value + ' value'); } }); console.log(p.test_test); console.log(p.test) p.qqq = "test"; 

结果:

 read request to test_test property 1234 read request to test property Meh write request to qqq property with test value 

如果你真的坚持使用test.hello = "world"语法来检测现有属性的变化,那么你将不得不等待Object.watch成为下一个EcmaScript标准的一部分。

幸运的是,您可以使用Object.defineProperty在EcmaScript 5中执行相同的Object.defineProperty 。 Eli Gray制作了一个很棒的Object.watch polyfill ,你可以这样调用它:

 var test = {}; test.watch("hello", function(propertyName, oldValue, newValue) { console.log(propertyName + " has been set to " + newValue); }); test.hello = "world"; // triggers the watch handler 

你可以修改他的代码来在getter触发一个不同的处理器,这样你就可以检测到属性访问。

不幸的是, 浏览器支持仅限于现代浏览器,包括Internet Explorer 9,Firefox 4,Chrome,Opera 12和Safari 5。

如果你想在一个新属性被设置的时候触发一个处理程序,你将会遇到更多麻烦。 你可以做的最好的做法是把你的对象包装在一个代理中,并放置一个陷阱。 然后,您可以通过testingthis.getOwnPropertyDescriptor this.getOwnPropertyDescriptor(name)返回“真值”来检测属性是否已经存在。 代理API是非常实验性的,只有less数浏览器提供了原型实现。 您可能需要等待相当长的一段时间才能获得一个完整的API与体面的浏览器支持。

 var test = {}; Object.defineProperty(test, "hello", { get : function () { return this._hello; }, set : function (val) { alert(val); this._hello = val; } }); test.hello = "world"; 

就是这样 但是它不适用于旧版浏览器。

你可以在这里find更多的select: http : //robertnyman.com/javascript/javascript-getters-setters.html

您需要一个提供键值观察和绑定的库。

烬金属就是这样一个库。

基本上你可以创build对象,并且可以在这些对象的属性上注册观察者。

 var obj = Em.Object.create({ val: null valDidChange:function(){...}.observes('val') }); 

valDidChange将在val属性更改时触发,所以

 obj.set('val', 'newValue'); 

将导致观察员开火。

这样的事情呢? 这是一个jsfiddle。

 var objectManager = function(obj, setCallback){ this.obj = obj; this.setCallback = setCallback; }; objectManager.prototype.setProperty = function(prop, value){ this.obj[prop] = value; this.setCallback(prop); }; objectManager.prototype.getObj = function(){ return this.obj; }; // USAGE: var testMgr = new objectManager({}, function(prop){ console.log(name + ' has been set.'); }); testMgr.setProperty("hello", "world"); //should log "hello has been set.";