简体   繁体   中英

Listen to state and function invocations

Is it possible to listen to any function invocation or state change

I have a object that wrap another

function wrapper(origiObj){
   this.origObj = origObj;
}
var obj = wrapper(document);//this is an example
var obj = wrapper(db);//this is an example

now everytime someone tries to invoke obj.innerHTML or obj.query(..)

I would like to listen to that..

Yes, it's possible: functions are easy, and properties has to be watched

function FlyingObject(obj){
    this.obj = obj;
    for(var p in obj){
        if(typeof obj[p] == 'function'){
            console.log(p);
            this[p] = function(){
                console.log("orig func");
            };
        }else{
            this.watch(p,function(){
                console.log("orig property");
            });
        }
    }
}
var obj = {
    f:function(a,b){ return a+b},
    m:1
};
var fo = new FlyingObject(obj);


fo.m = 5;

fo.f(1,4);

If your browser/node.js doesn't support Object.watch, check this out: Object.watch() for all browsers?

Yes you can, define a getter / setter for properties and a shadow function for the function like this: http://jsfiddle.net/fHRyU/1/ .

function wrapper(origObj){
   var type = origObj.innerHTML ? 'doc' : 'db';
   if(type === "doc") {

      var orig = origObj.innerHTML;

      origObj.__defineGetter__('innerHTML',
                               function() {
       // someone got innerHTML
          alert('getting innerHTML');
          return orig;
      });

      origObj.__defineSetter__('innerHTML',
                               function(a) {
       // someone set innerHTML
          alert('setting innerHTML');
          orig = a;
      });

   } else if(type === "db") {

       var orig = origObj.query;

       origObj.query = function() {
           //someone called query;
           alert('calling query');
           orig.apply(this, arguments);
       };

   }

   return origObj;
}

var obj = wrapper(document.body);
obj.innerHTML = 'p';
alert(obj.innerHTML);

var db = function() {}
db.query = function() {alert('foo');}

obj = wrapper(db);
obj.query();

edit: "Deleting" answer since it's tagged node.js, leaving it in case it happens to be useful to anyone else:

The general answer is no, it isn't. At least not in every browser, so any solution anyone gives isn't going to work in many cases.

There are a few things that can work, but again there is horrible support for them:

  • dom modified events (FF only, I believe)
    • DOMAttrModified
    • DOMNodeInserted
    • DOMNodeRemoved
    • etc
  • object.watch (FF only)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM