Asim Zaidi
Asim Zaidi

Reputation: 28284

Unable to call method after class instantiation

var myclass = {
    init:function () {
        this.customer = null;
    },
    test : function(data){
      alert(testing);
    }
};

I am instantiating myclass like above, and later on I am trying to call a method test of the class, but it doesnt work. What am I doing wrong?

var testClass = new myclass.init();
testClass.customer = 'John B';
testClass.test(); //doesnt alert 1

Instead of getting the alert, for some reason I get this error:

Uncaught TypeError: Object [object Object] has no method 'test'

Upvotes: 0

Views: 146

Answers (3)

bfavaretto
bfavaretto

Reputation: 71908

You have to define your "class" as a constructor function, not an object literal:

var MyClass = function(){
    this.init = function () {
        this.customer = null;
    };

    this.test = function(data){
      alert('testing');
    };
};
var testClass = new MyClass();
testClass.init();
testClass.customer = 'John B';
testClass.test(); //alerts 'testing'

Then the init function is not really needed, you can add that logic to the constructor itself:

var MyClass = function(){
    this.customer = null;

    this.test = function(data){
      alert('testing');
    };
};
var testClass = new MyClass();
testClass.customer = 'John B';
testClass.test(); //alerts 'testing'

You can also add your methods to MyClass.prototype instead of declaring them inside the constructor. For the difference between the two, refer to Use of 'prototype' vs. 'this' in JavaScript?.

Finally, if you want to stick to your object literal, you have to use Object.create:

var myclass = {
    init:function () {
        this.customer = null;
    },
    test : function(data){
      alert('testing');
    }
};

var testClass = Object.create(myclass);
testClass.customer = 'John B';
testClass.test(); //alerts 'testing'

Upvotes: 4

Sethcran
Sethcran

Reputation: 788

Another implementation, with some explanations:

var MyClass = function() {
    this.customer = null;
};

// Any functions need to be added to the prototype,
// and should use the keyword this to access member fields.
// Doing this allows for a performance gain over recreating a new function definition
// every time we create the object, as would be the case with this.test = function() { ... }
MyClass.prototype.test = function(data){
    alert('testing');
};

// At this point, MyClass is a constructor function with all of it's
// prototype methods set, ready to be instantiated.

var testClass = new MyClass();
testClass.customer = 'John B'; // May also want to consider moving this into the constructor function as a parameter.
testClass.test();

JSFiddle

Upvotes: 2

mohkhan
mohkhan

Reputation: 12305

You have to add the test method a prototype of init. Like this...

var myclass = {
    init:function () {
        this.customer = null;
    },
    test : function(data){
      alert(testing);
    },
};

myclass.init.prototype = myclass;

This way all objects will inherit from myclass object.

Upvotes: 0

Related Questions