2

I try call method doSomething in hello function in student object without prototype just attach on this. Student extends Person object.

function Person(name){
    this._name = name;
    this.doSomething = function () {
        console.log('doSomething');
     }
}

function Student (name, grade) {
    this._name = name;
    this._grade = grade;

    this.hello = function  () {
        //How i can call doSomething() here
    }
}
IvanBozhakov
  • 33
  • 1
  • 7
  • 4
    How do you intend to make: `Student extends Person`? – Nagaraj Tantri Apr 18 '15 at 15:03
  • You're putting the "doSomething" method on each Person *instance*. Inheritance in JavaScript works through the prototype chain, so the structure you're setting up is not the best way to do it. Making the Student prototype be an *instance* of Person wouldn't really make sense. – Pointy Apr 18 '15 at 15:07
  • student doesn't extend person in your example. you could create a new person instance within student and use it's functions. – dewd Apr 18 '15 at 15:14

2 Answers2

2

You need to .call() the parent in the constructor so Student has everything that Person does, then do this.doSomething():

function Student (name, grade) {
    Person.call(this, name); // extends
    this._grade = grade;

    this.hello = function  () {
        this.doSomething();
    };
}

Then you can call hello() from a student instance:

var student = new Student("t","A")
student.hello(); // logs 'doSomething'

Example Fiddle

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Spencer Wieczorek
  • 21,229
  • 7
  • 44
  • 54
  • i'd give you 2^'s if i could. :) – dewd Apr 18 '15 at 15:17
  • I'd consider this as bad practice, since the constructor always creates new functions on runtime each time you call `new Student()`. That's why you should `prototype` when using JavaScript. – jehna1 Apr 18 '15 at 15:18
  • @jehna1 I went with this way since it's easy to implement with the current code the OP has. There is only a singe method, so the performance improvement by prototypes will be minimal. I was going to do a prototype example as well, but you already added that as an answer :) – Spencer Wieczorek Apr 18 '15 at 15:22
  • I was just wondering what would have happened without prototypes – IvanBozhakov Apr 18 '15 at 15:24
  • @SpencerWieczorek Yes, I agree your answer fits more of the original question. Nice :) – jehna1 Apr 18 '15 at 15:25
1

Your code should be (with proper JS class extension):

function Person(name){
    this._name = name;
}
Person.prototype.doSomething = function() {
    console.log('doSomething');
}

function Student (name, grade) {
    this._name = name;
    this._grade = grade;
}
Student.prototype = Object.create(Person.prototype); // extends
Student.prototype.hello = function  () {
    // Just call it like this:
    this.doSomething();
}
jehna1
  • 3,110
  • 1
  • 19
  • 29
  • nice work. you have a point about prototyping. particularly relevant with small mobile devices. – dewd Apr 18 '15 at 15:22
  • That is [not proper class extension](https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here)! – Bergi Apr 18 '15 at 15:25
  • Thanks @Bergi, better now? – jehna1 Apr 18 '15 at 15:27
  • no, [that](http://stackoverflow.com/q/3034941/1048572)'s not what I meant. Please read PointedEars' answer in the linked post to understand why you should not use `new` at all here. – Bergi Apr 18 '15 at 15:30
  • @Bergi PointedEars answer is quite drawn out. But I think the suggestion is to inherit via the dummy object, creating an instance of the dummy object - which has no properties so shouldn't do anything dangerous. – dewd Apr 18 '15 at 15:50
  • @dewd: Yeah, only that no dummy object is needed with `Object.create` – Bergi Apr 18 '15 at 16:01
  • @Bergi the answer is proper considering resource sharing between classes (comparing to the original code). I don't want to argue whether the prototype inheritance itself is broken or not in JavaScript. – jehna1 Apr 18 '15 at 16:23
  • 1
    @jehna1: Yes, considering prototypical resource sharing is proper (and I don't think JavaScript is broken). I'm just saying that using `new Person` to create prototype objects is not proper, you should do `Object.create(Person.prototype)` instead. – Bergi Apr 18 '15 at 16:33
  • 1
    @Bergi I understand that using `Object.create` yields the result you commonly are trying to achieve (not calling the prototype object's constructor) and is closer to how other OOP languages are behaving. I suppose it's the matter of understanding how both of them work and using the method appropriate for each situation. You're right that in this example it'd been wiser to use `Object.create` since the constructor of `Person` is not needed to run. I'll change it :) – jehna1 Apr 18 '15 at 17:16
  • Object.create is fine if you don't have to support IE8. Fewer and fewer organisations require it. – dewd Apr 18 '15 at 17:22