2
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

4
  • This is so complicated it's hard to get you intent. Whatever it is, there's a simpler way to achieve it. Commented Jan 27, 2014 at 17:36
  • His intent seems to be to inherit the Greeter object, and override the constructor Commented Jan 27, 2014 at 17:38
  • Seemingly you already have a jsFiddle. You could have posted the link at the same time, so it would be easier for us to play with the code :). Commented Jan 27, 2014 at 17:50
  • Sorry about that next time if I have a question I will be doing it. @dystroy is it a bad way of prototyping in javascript ? It would be a great support if you could explain me further Commented Jan 27, 2014 at 17:56

5 Answers 5

2

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);
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you, and I got the issue any ways I really appreciate your time on this.
but I have put a log inside Greeter and it does getting logged in console but with an undefined greeting.
@CodeDecode Yes, because of this line: Greeting.prototype = new Greeter();. To do your inheritance stuff, you are calling the Greeter function, with no parameters - hence the undefined.
Have one more question is this the proper way of doing inheritance in javascript? I believe I'm not bothering you. Because I got confused with one of the comment posted by @crush
@CodeDecode The second option from above is what you want. I don't know how I confused you. You did the first option above, which is NOT what you wanted to accomplish.
|
2

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

1 Comment

Thank you, and I got the issue any ways I really appreciate your time on this.
1

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());

Comments

1

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.

Comments

0

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.

1 Comment

Be careful with arguments.callee, ECMAScript 5 forbids its use in strict mode.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.