2

I have:

Master object

function Fruit() {
    this.type = "fruit";
}

Sub-object:

function Bannana() {
    this.color = "yellow";
}

Inherit master properties

Bannana.prototype = Object.create( Fruit.prototype );

var myBanana = new Bannana();

console.log( myBanana.type );

Outputs: undefined. Why is this not displaying "fruit" as the outcome?

Robert
  • 10,126
  • 19
  • 78
  • 130
  • 2
    `Bannana.prototype =Object.create( new Fruit );` would probably do what you want – dandavis Jun 22 '15 at 22:46
  • 2
    @dandavis: It does, but it's not better than `Bannana.prototype = new Fruit();` – Felix Kling Jun 22 '15 at 22:49
  • why do not go usual way, like: "public class Bannana extends Fruit"? – Yevgeniy Afanasyev Jun 22 '15 at 22:51
  • @YevgeniyAfanasyev: i don't think that's the usual way since its not valid JS... – dandavis Jun 22 '15 at 22:51
  • @dandavis: It's valid ES6/ES2015. – Felix Kling Jun 22 '15 at 22:52
  • possible duplicate of [JavaScript inheritance and the constructor property](http://stackoverflow.com/questions/8093057/javascript-inheritance-and-the-constructor-property) – Mulan Jun 22 '15 at 22:53
  • ES6 is not a usual way of coding anything, at least not until it come out... – dandavis Jun 22 '15 at 23:01
  • @dandavis: ES6 was officially released last week. http://www.ecma-international.org/ecma-262/6.0/ . If you are not already using the new syntax with all the tools out there, it's your loss ;) – Felix Kling Jun 22 '15 at 23:02
  • that's good news, but Yevgeniy's code gives me a syntax error when i try it in chrome and firefox... any guess on when ES6 will be out in the wild to use in production? i would love to start using fat arrows... – dandavis Jun 22 '15 at 23:03
  • @dandavis: Browsers will likely gradually implement new features. E.g. promises are already available in most browsers. You really should just use [Babel](https://babeljs.io/) and compile your code. – Felix Kling Jun 22 '15 at 23:06

3 Answers3

4

Why is this not displaying "fruit" as the outcome?

Because you are never setting type on the new object.

type isn't a property of Fruit.prototype, and all that Bannana.prototype = Object.create( Fruit.prototype ); does is make the properties of Fruit.prototype available to each Banana instance.

type is set by the Fruit function. But if you look at your code, nowhere are you executing Fruit! The line this.type = "fruit"; is never executed! The type property does not magically come to existence.

So in addition to setting the prototype, you have to execute Fruit. You have to call the parent constructor (just like you do in other languages (and ES6 now) via super):

function Bannana() {
    Fruit.call(this); // equivalent to `super()` in other languages
    this.color = "yellow";
}

In the new JavaScript version (ES6/ES2015) you would use classes instead:

class Banana extends Fruit {
    constructor() {
        super();
        this.color = 'yellow;
    }
}

This does the same thing, but hides it behind the class syntax for ease of use.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • as shown, is there any use of actually duping the proto since all the interesting "inherited" props are own properties ? – dandavis Jun 22 '15 at 22:51
  • @dandavis: Not in this case but in general yes. – Felix Kling Jun 22 '15 at 22:52
  • Nicely done Felix. Totally understand it better now! Thanks! – Robert Jun 22 '15 at 22:53
  • Ouch! That new JavaScript is distancing itself from prototypes and looks more class based. – Robert Jun 22 '15 at 22:57
  • 1
    @RobertRocha: Not really, it still creates the `Banana.prototype` object as you'd expect. It's mostly the looks. – Bergi Jun 22 '15 at 22:58
  • @RobertRocha: afaik, the new JS doesn't add anything fundamental that ES5 lacks, it just makes it (a ton) prettier and more intuitive by providing syntactic sugar to look like older OOP langs. – dandavis Jun 22 '15 at 22:58
  • @RobertRocha: Prototypes are just becoming an implementation detail, similar to how it is in Python. – Felix Kling Jun 22 '15 at 23:00
  • @Felix Kling, Please, add "Bannana.prototype = new Fruit();" as a possible case in your answer, to have it explicit. Thanks. – Yevgeniy Afanasyev Jun 22 '15 at 23:09
  • 1
    @YevgeniyAfanasyev: I won't because I don't want to promote this style. See my answer here: http://stackoverflow.com/q/17392857/218196 – Felix Kling Jun 22 '15 at 23:10
0

This is so cool. If you go this way:

function Fruit() {
    this.type = "fruit";
}
function Bannana() {        
    this.color = "yellow";
}
Bannana.prototype =  new Fruit;
Bannana.prototype.type='flower';
var myBanana = new Bannana();
console.log( myBanana.type );

you will get a "flower", but if you go this way:

function Fruit() {
    this.type = "fruit";
}
function Bannana() {
    Fruit.call(this);
    this.color = "yellow";
}
Bannana.prototype.type='flower';
var myBanana = new Bannana();
console.log( myBanana.type );

You will get a "fruit";

I believe no explanation needed, right?

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
-3

You never put anything on the Fruit prototype object. Your constructor initializes the instances, not the prototype.

If you had:

Fruit.prototype.type = "fruit";

then your code would work as you expect.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • I thought that `Bannana.prototype = Object.create( Fruit.prototype );` would cause inheritance of the master object properties that already have values. – Robert Jun 22 '15 at 22:43
  • 1
    @RobertRocha it would. Your code does not put any properties on the `Fruit` prototype. The code in your `Fruit` constructor, to be specific, does not do that. – Pointy Jun 22 '15 at 22:46
  • 1
    @RobertRocha: JavaScript is less magical then you seem to think. – Felix Kling Jun 22 '15 at 22:47
  • Sorry I am new to JavaScript and trying to learn the ropes of prototypes and how they work. In lots of code on MDN I see it use the `Object.create()` function when extending master objects. For some reason Bannana.prototype = new Fruit() seems to do the trick. – Robert Jun 22 '15 at 22:52
  • They also aren't calling the Fruit constructor from the Bannana constructor. – jfriend00 Jun 22 '15 at 22:56