2011-03-31 117 views
3

函数是对象:Javascript,当对象的属性发生变化时回调?在JavaScript

var x = function(){}; 
x.y = 1; 
console.log(x.y); //Prints 1 

有什么办法Ÿ更改时调用一个函数?

我这样做的理由是,我试图重写jquery的“$”函数,以便可以对性能进行基准测试。当JS运行$('mySelector')时它工作正常。但是,使用$.fn.myPlugin创建的插件将更改被覆盖的对象I中的属性,而不是原来的。

回答

0

我所用半狄的defineGetter建议解决,而是通过属性循环的方法原始对象。

getAttr = function(att) { 
    return function() { return eval("originalObject."+att) }; 
} 
//Delegate all attribute access to original object 
for (var att in originalObject) { 
    overRiddenObject.__defineGetter__(att.toString(), getAttr(att)); 
} 

这里是全段,我可以在我的代码坚持简介jQuery选择:

var original$ = $; 
$ = function() { 
    //Ignore document.ready function calls 
    if (typeof(arguments)[0] === 'function') { 
     return original$.apply(this, arguments); 
    } 

    t1 = new Date().getTime(); 
    // Run each selector 100 times since we can only time it to the millisecond 
    for (var i=0; i<100; i++) 
     x = original$.apply(this, arguments); 
    t = new Date().getTime()-t1; 
    // Print selector name, time taken and number of elements matched 
    console.log(arguments," "+t+"ms"+" ("+x.length+" element(s))"); 
    return x; 
}; 
getAttr = function(att) { 
    return function() { return eval("original$."+att) }; 
} 
//Delegate all attribute access to original object 
for (var att in original$) { 
    $.__defineGetter__(att.toString(), getAttr(att)); 
} 

这也许可以更好的使用风格封闭的完成,但它的工作原理。

另外它只会在jQuery插件上工作,当你从(function($) {...))(jQUery)删除“$”。

这可以通过重写这个来解决使用扩展和覆盖在选择过程中调用的方法 - 我正在研究使这个可插入的东西。

1

我相信你要找的是JavaScript setters。注意研究浏览器支持的难点。

以下示例来自MDN文档。首先,当你创建自己的对象:

var o = {a: 7, 
     get b() {return this.a + 1;}, 
     set c(x) {this.a = x/2}}; 

其次,当你扩展现有的原型:

var d = Date.prototype; 
d.__defineGetter__("year", function() { return this.getFullYear(); }); 
d.__defineSetter__("year", function(y) { this.setFullYear(y); }); 
+0

嗯不完全,这将只允许我通过名称挂钩属性,我需要委托他们所有的原始对象 – bcoughlan 2011-03-31 16:42:17

1

没有办法做到这一点,将在所有浏览器中工作。吸气剂和吸附剂很好,但当你必须支持IE6或IE7时,它们完全没有用处。