2011-03-31 116 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時,它們完全沒有用處。