Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #24833

Re: Bind custom function to the all Function objects

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups comp.lang.javascript
Subject Re: Bind custom function to the all Function objects
Date 2014-06-14 15:55 +0200
Organization PointedEars Software (PES)
Message-ID <1859569.COELiHlnRc@PointedEars.de> (permalink)
References (1 earlier) <1649322.pjBWu2vbqe@PointedEars.de> <94a15$539b16e4$6def49ce$21821@nntpswitch.blueworldhosting.com> <2459085.3y454gxjXg@PointedEars.de> <1e6b6$539b6200$6def49ce$25031@nntpswitch.blueworldhosting.com> <1464959.oZ30Yp1K6V@PointedEars.de>

Show all headers | View raw


Thomas 'PointedEars' Lahn wrote:

> Cezary Tomczyk wrote:
>> However, I think that in reality it's not possible to do that because
>> then changes needs to be done everywhere in the code. So, I thought that
>> it would be better to "wrap" every function/method globally (not sure if
>> I described it correctly) so that every call of function/method in web
>> application first will call custom function before and put information's
>> from console.count. In that way I could measure how many times every
>> function/method is called. That's my goal.
> 
> It is possible to wrap all *your* functions (that you *know*) simply by
> replacing them (I do something similar in jsx.dom.addEventListener() in
> order to emulate EventTarget::addEventListener() when unavailable):
> 
>   var myFunction = function () {
>     console.log("myFunction");
>   };
> 
>   /**
>    * Adds a call counter to a function.
>    *
>    * NOTE: Must pass object reference and property name for a general
>    *       solution because there is no call-by-reference
>    *
>    * @param {Object} obj
>    * @param {String} propName
>    * @return {Function}
>    *   Decorated function
>    */
>   function addCounter (obj, propName)
>   {
>     var original_function = obj[propName];
> 
>     if (typeof original_function != "function")
>     {
>       throw new TypeError(
>         "addCounter: obj[propName] must refer to a function");
>     }
> 
>     var decorated = function () {
>       console.count("myFunction");
>       original_function.apply(this, arguments);
>     };
> 
>     obj[propName] = decorated;
> 
>     return decorated;
>   }
> 
>   /* 
>    * Example: in global context; cannot generally decorate local functions
>    */
>   addCounter(this, "myFunction");

Slight improvement (untested):

/**
 * Decorates a function with code to be executed before and/or after
 * it is called.
 * 
 * @param {Object|Function} obj
 * @param {String|Null|Undefined} propName
 * @param {Function} before
 *   Code to be executed before the original function.  Called with
 *   the same <code>this</code> value and arguments as the original
 *   function.
 * @param {Function} after (optional)
 *   Code to be executed after the original function.  Called with
 *   the same <code>this</code> value as the original function.
 *   The arguments lists consists of the return value of the
 *   original function followed by its argument list.
 * @return {Function} Decorated function
 */
function decorate (obj, propName, before, after)
{
  var original = (propName == null ? obj : obj[propName]);
 
  if (typeof original != "function")
  {
    throw new TypeError(
      "decorate: obj[propName] or obj must refer to a function");
  }
 
  var decorated = function () {
    if (typeof before == "function")
    {
      before.apply(this, arguments);
    }

    var result = original.apply(this, arguments);

    if (typeof after == "function")
    {
      after.apply(this, [result].concat([].slice.call(arguments)));
    }
  };
 
  if (propName != null)
  {
    obj[propName] = decorated;
  }
 
  return decorated;
}

/* 
 * Example: in global context; cannot generally decorate local functions
 */
myFunction = decorate(myFunction, null, function () {
  console.count("myFunction");
});

decorate(foo, "bar",
  function () {
    baz ();
  },
  function (result) {
    bla(result);
  });

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Bind custom function to the all Function objects Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2014-06-13 16:32 +0200
  Re: Bind custom function to the all Function objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-13 16:56 +0200
    Re: Bind custom function to the all Function objects Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2014-06-13 17:21 +0200
      Re: Bind custom function to the all Function objects "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2014-06-13 08:39 -0700
      Re: Bind custom function to the all Function objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-13 19:01 +0200
        Re: Bind custom function to the all Function objects Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2014-06-13 22:41 +0200
          Re: Bind custom function to the all Function objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-14 01:57 +0200
            Re: Bind custom function to the all Function objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-14 15:55 +0200
            Re: Bind custom function to the all Function objects Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2014-06-16 21:55 +0200
              Re: Bind custom function to the all Function objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-16 23:26 +0200
  Re: Bind custom function to the all Function objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-18 21:04 +0200

csiph-web