-1

I have some functions defined inside an object:

var functions = {
    __construct: function(){
        console.log(this);
        this.prototype.__construct(); // <problem
    }
};

I merge this object with another one that is a function (after I create a new instance of the function):

var plugin = function(){};

plugin.prototype.__construct = function(){
    console.log('parent');
};

var i = new plugin();
i = $.extend({}, i, functions);

But after that when I try to call the __construct function:

i.__construct();

I get this error:

Uncaught TypeError: Cannot call method '__construct' of undefined

It's because this line:

this.prototype.__construct();

I tried to see if I can call the parent constructor function from the child constructor, but it appears that the object doesn't have a prototype? wtf?

Phil
  • 157,677
  • 23
  • 242
  • 245
Alex
  • 66,732
  • 177
  • 439
  • 641
  • 2
    _"after I create a new instance of the function"_ -- Why after? – elclanrs Nov 29 '13 at 02:29
  • because $.extend returns a simple object, not a function, and I can't call a simple object – Alex Nov 29 '13 at 02:32
  • 1
    ^ Probably because the OP used `$.extend`. That's a pretty ridiculous thing to down vote a question for. I'm not saying the question should or shouldn't be down-voted, but it shouldn't be down-voted for adding that tag. – Vinay Nov 29 '13 at 02:33
  • @thenewseattle I guess $.extend is something that comes with ECMA then is it? – HMR Nov 29 '13 at 02:38
  • @thenewseattle Edit the question and remove the tag if you think it's not relevant. Questions should not be up/down voted if they're just a little sloppily formed. Down voting for that reason doesn't improve the quality of the resources on this site. – Kitsune Nov 29 '13 at 02:42
  • But you can extend the prototype of your constructor before creating an instance. A prototype is a simple object too. – elclanrs Nov 29 '13 at 02:49

1 Answers1

2

Not sure what you're trying to do here but i does have a __construct function when using the code you provided:

  var functions = {
        __construct: function(){
          console.log(this);
          this.prototype.__construct(); // <problem
        }
      };
var plugin = function(){};    
plugin.prototype.__construct = function(){
  console.log('parent');
};
var i = new plugin();
i = $.extend({}, i, functions);
console.log(i.__construct===functions.__construct);//true
console.log(i.__construct===plugin.prototype.__construct);//false

Not sure what you think this.prototype is going to be, maybe this answer will clear up what prototype is used for (shared members) and what this means (instance specific). You can shadow shared members that are defined in the prototype further down the prototype chain or in an instance but that's not what you're doing here.

If you dynamically want to extend an instance created with a constructor function you can do something like this:

var functions = {
    __construct: function(){
      this.constructor.prototype.__construct.call(this);
    }
};

var Plugin = function(){};
Plugin.prototype.__construct = function(){
  console.log('parent');
};

var i = new Plugin();
i = $.extend(i,functions);
i.__construct();
Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • i understand that every object will share the things from the prototype, but i can't access them from `this.prototype` :| – Alex Nov 29 '13 at 02:43
  • @Alex Object instances do not have prototype, functions have prototype. If you create an object instance with a constructor function then then the constructor function's prototype will be the first prototype used in the prototype chain when you request a member that can't be found on the instance directly. You can't access an instance prototype from the instance because the instance doesn't have a prototype. The intro about constructor functions and prototype will explain this also. – HMR Nov 29 '13 at 02:45
  • ok i understand now, sorry :( so there's no real way to extend functions in javascript and be able to call parent functions :( – Alex Nov 29 '13 at 03:01
  • @Alex The link in my answer shows how to do it with constructor functions and prototype. It's kind of rigid and assumes that you define your Object's first (their inherit stricture and or mix ins). I can try and found out a more dynamic way of mixing in functions with an instance of Plugin. – HMR Nov 29 '13 at 03:19
  • @Alex Updated the answer with an example how to extend existing instances. Usually you define the structure first and then create instances based on that but you can dynamically add and remove behavior from existing objects if you wish to do so. – HMR Nov 29 '13 at 03:35
  • `this.constructor.prototype.__construct.call(this);` doesn't seem to work. I get `Uncaught RangeError: Maximum call stack size exceeded ` and the console crashes :( – Alex Nov 29 '13 at 10:55
  • @Alex Are you sure you copy and pasted the code in my answer because I've tested it an don't get that error. – HMR Nov 29 '13 at 11:31