0

I'm trying to assign a prototype inside a namespace using the following, (everything is wrapped in a global object):

prototypeObjects: {

        Person : function(config){

            var that = this;

            this.name = config.name;
            this.age = config.age;

            console.log(that);

            that.prototype.working = function(){

                console.log(this.name + 'is working');

            };

    },

},

I'm then using this in the console to check it:

var me = new global.prototypeObjects.Person({name:'Mike', age:'40'});

which gives this error:

TypeError: Cannot set property 'working' of undefined

However, if I am explicit in assigning the prototype, i.e.:

prototypeObjects: {

        Person : function(config){

            var that = this;

            this.name = config.name;
            this.age = config.age;

            console.log(that);

            **global.prototypeObjects.Person**.prototype.working = function(){

                console.log(this.name + 'is working');

            };

        }



    },

Then it works as expected and i get the following:

global.prototypeObjects.Person {name: "Mike", age: "40", working: function}

and me.working() logs out 'Mike is working'

Can somebody explain why I can't use 'this' in this instance?

2 Answers2

1

You define the prototype function in the constructor's body, you should define the prototype functions outside the function body:

var global={};
global.pototypeObjects= {
   Person : function(config){
     this.name = config.name;
     this.age = config.age;
   }
};
global.pototypeObjects.Person.prototype.working=function(){
  console.log(this.name + " is working");
};
var p = new global.pototypeObjects.Person(
  {name:"jon",age:22}
);
p.working();//jon is working

Here is some basic explanation about prototype and setting up inheritance: Prototypical inheritance - writing up

It's better not to use var in constructor functions as they will create closures and these objects take more cpu to initialize and more memory.

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • Marked as correct for the detail and the external link. Working perfectly now, Thank-you sir! – Michael Snow Jul 02 '13 at 00:18
  • +1 but using "var" in a constructor has nothing to do with whether closures are created or not. Closures are a consequence of creating functions that persist beyond the life of their enclosing scope. – RobG Jul 02 '13 at 00:20
  • @RobG A closure is the return value of a function that has an environment associated to it to accommodate for variables declared in the function with var not going out of scope when the function returns. If I have `var name = ""` in person and create a new person() then what's returned is a closure because an environment is associated with person to make `name` available. – HMR Jul 02 '13 at 00:25
  • @RobG Sorry, you are correct, closures are created when defining functions in the constructor's body. This is usually the case when you want to use "private" variables defined with `var` because these are not available in prototype functions (outside the constructors body). But when defining a variable with var in the body and using it right there should not create closures. – HMR Jul 02 '13 at 00:37
  • @HMR—yes. Also, formal parameters create local variables as if by use of "var". Strictly, any "inner" function has a reference to the entire outer function's scope chain and hence creates the environment for a closure to be created. Whether one is or not depends on the persistence of the inner function. :-) – RobG Jul 02 '13 at 05:22
0

Because you've already instantiated the object. prototype exists on the class, not the object. You could just do:

this.working = function() {}

Otherwise, you should move it outside the constructor.

kalley
  • 18,072
  • 2
  • 39
  • 36
  • 1
    Why would you declare a function in the constructor's body? The function does the same for each instance of person so should and can be shared but this way every person instance has it's own working function that will take extra cpu to initialise and more memory to store. – HMR Jul 02 '13 at 00:17