CodeDecode
CodeDecode

Reputation: 401

Issue While Prototyping In javascript

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

var Greeting = (function(){
    Greeting.prototype = new Greeter();        
    Greeting.prototype.constructor = Greeter;
    function Greeting(greeting){
    } 
    return Greeting;
})();



var greeting = new Greeting("World");
alert(greeting.greet());

I'm trying to manipulate inheritance using javascript prototyping. I have a class structure like above. But when I call the greet method it display some thing like the below image shows. Can anybody guid me on this ?

enter image description here

Upvotes: 2

Views: 370

Answers (5)

Mehran Hatami
Mehran Hatami

Reputation: 12961

change the Greeting class like this:

var Greeting = (function(){
    function Greeting(greeting){
        Greeter.apply(this, arguments);
    }
    Greeting.prototype = new Greeter();        
    Greeting.prototype.constructor = Greeter;
    Greeting.superClass = Greeter;

    return Greeting;
})();

or if you want to create a general solution for all of your inheritance model, do this:

var Greeting = (function(){
    var Greeting = function $SubClass(greeting){
        $SubClass.prototype.constructor.apply(this, arguments);
    }
    Greeting.prototype = new Greeter();        
    Greeting.prototype.constructor = Greeter;

    return Greeting;
})();

The important point in this part:

var Greeting = function $SubClass(greeting){};

is when you directly assign the function to a variable, you would have access to your function based on its label ($SubClass) only in the function context.

Upvotes: 0

elixenide
elixenide

Reputation: 44831

When you call greeting.greet(), this.greeting is undefined, thus the problem.

Explanation:

Try this code:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
console.log('Log 1: ' + Greeter);

var Greeting = (function(){
    console.log('Log 2: ' + Greeting);
    Greeting.prototype = new Greeter();        
    console.log('Log 3: ' + Greeting);
    Greeting.prototype.constructor = Greeter;
    console.log('Log 4: ' + Greeting);
    function Greeting(greeting){
    } 
    console.log('Log 5: ' + Greeting);
    return Greeting;
})();

console.log('Log 6: '+Greeting);


var greeting = new Greeting("World");
alert(greeting.greet());

You will see that Greeting is just an empty function, but with Greeter as the prototype. So, new Greeting('World') creates the following function:

function Greeting(greeting){
}

with a prototype containing greeting (undefined), constructor (a function), and greet (a function). Greeting.prototype.greet, in turn, has this definition:

Greeting.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

But this.greeting is undefined in this context, because this refers to Greeting.prototype.greet, not Greeter. Thus, these lines:

var greeting = new Greeting("World");
alert(greeting.greet());

fail, because greeting.greet() returns Hello, concatenated with an undefined value.

Upvotes: 1

Alex
Alex

Reputation: 11245

You call greet method on Greeting context which don't have greeting property.

And there is no reason to wrap code in IIEF in your case, because there is no private vars, so (it works):

var Greeter = function (message) {
    this.greeting = message;
};

Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

var Greeting = function (greeting){
    Greeter.call(this, greeting)
} 

Greeting.prototype = new Greeter();        

var greeting = new Greeting("World");
alert(greeting.greet());

Upvotes: 1

kapa
kapa

Reputation: 78681

You are never invoking the "constructor" function Greeter when you are creating the Greeting object. So the this.greeting = message; line never runs, that is why it is undefined.

You have to either insert that line manually:

function Greeting(greeting){
    this.greeting = greeting;
}

or invoke the parent constructor:

function Greeting(greeting){
    Greeter.call(this, greeting);
}

Upvotes: 2

xspydr
xspydr

Reputation: 3050

In your "greet" method of your Greeter you call this.greeting. However, in your Greeting object you haven't defined a "greeting" method...

Upvotes: 2

Related Questions