0

I'm trying to add a hook to each of the functions in the object, follows are my code and it's runs good.

    function foo(){}
    foo.beforeMethodHook = function(){console.log('Hook was called.');}
    foo.getInstance = function(){
        var newInstance = new foo;
        var funcNames = Object.getOwnPropertyNames(foo);
        for(i in funcNames){
            var funcName = funcNames[i];
            if(funcName == 'getInstance' || funcName == 'beforeMethodHook' || Object.hasOwnProperty(funcName)) continue;
            newInstance[funcName] = function (){
                foo.beforeMethodHook();
                return foo[this].apply(foo,arguments);
            }.bind(funcName);
        }
        return newInstance;
    }
    foo.test1 = function(arg1){console.log('test1 was called. arg1 = ' + arg1);return true;}
    foo.test2 = function(arg1,arg2){console.log('test2 was called. arg1 = ' + arg1 + ' , arg2 = ' + arg2);return true;}
    //Test
    var f = foo.getInstance();
    f.test1('ahaha');
    f.test2('heihei','houhou');

As IE10- don't support function(){}.bind(), I tried to change the .bind() to (function(){})() which follows

    newInstance[funcName] = (function (){
        foo.beforeMethodHook();console.log(arguments);
        return foo[funcName].apply(foo,arguments);
    })(funcName);

But the problem comes, I lose arguments that f.test1('ahaha') has passed. the arguments array only gives ["test1"] which is the function name.

How can I fix that? Thanks in advance.

2

3 Answers 3

1

You can implement your own bind. Easy version:

if (!Function.prototype.bind) {
    Function.prototype.bind = function(that) {
        var fn = this;
        return function() {
            fn.apply(that, arguments);
        }
    };
}

or proper version:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

Code taken from:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Sign up to request clarification or add additional context in comments.

Comments

1

try using the alternative code for bind given over here

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fbind

Comments

0

you should do something like this

 newInstance[funcName] = (function (){
        console.log(arguments);
        return function(){
          foo.beforeMethodHook();
          foo[funcName].apply(foo,arguments);
        }
    })(funcName);

1 Comment

Not work. All the method will be override by the last method ever defined, which is "test2" in this case. "test1" no longer exist..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.