Cannot read property 'apply ' of undefined

I am trying to understand the .apply-method. So, I created the following code:

var o = new Object();
o.method = function(x, y) {
  return x + y
};

o.method = (function(original) {
  return function(x, y) {
    var a = 'A';
    var b = 'B';
    var result = original.apply(this, [a, b]);
    return result;
  }
})(o.method);

console.log(o.method(1, 2));

I thought that the last open and close parentheses could be empty and so the method o.method is invoked automatically. But with empty parentheses

o.method = (function(original) {
  return function(x, y) {
    var a = 'A';
    var b = 'B';
    var result = original.apply(this, [a, b]);
    return result;
  }
})();

o.method(1, 2);

I get the following error: Cannot read property 'apply' of undefined

Can someone please explain me why?

Kind regards Henning

2 answers

  • answered 2018-10-11 19:43 t.niese

    If you invoke the function function(original) {} you return a the function function(x, y) {} and you create a closure over the parameter original. So the code inside of the function(x, y) {} has allways access to what ever you passed to function(original) {}

    With:

    o.method = (function(original) {
      return function(x, y) {
        // ... 
      }
    })(o.method);
    

    You assign that returned function(x, y) {} function having a closure over original to o.method passing the original o.method as argument.

    If you now write o.method(1,2) you call that returned function(x, y) {}.

    If you called that function(original) {} with no argument (function(original) {})() then original is undefined and original.apply would result in your posted error.

  • answered 2018-10-11 20:04 Behrouz Pooladrag

    With some change your code is correct:

    var o = new Object();
    o.method2 = function(x,y){return x+y};
    
    o.method = (function (original){
        return function(x,y){
                var result = original.call(this, x,y);
            return result;
        }
    })(o.method2);
    

    Also for test and run:

    o.method(2,3)
    

    Result is 5

    Also with Apply:

    var o = new Object();
    o.method2 = function(x,y){return x+y};
    
    o.method = (function (original){
        return function(x,y){
                var result = original.apply(this, [x,y]);
            return result;
        }
    })(o.method2);
    

    Then test:

    o.method(2,3)
    

    Result is 5

    For more information about the usage of call() and apply() you can read this article: http://adripofjavascript.com/blog/drips/invoking-javascript-functions-with-call-and-apply.html