0

I know JavaScript inheritence is much different than typical OO languages (Java, c++, etc.). Searching around, there also seems to be many different ways to create classes and class hierarchies. Because of this I'm confused about JavaScript inheritence.

Given the following code

if (!com) var com = {};
if (!com.foobar) com.foobar = {};

com.foobar.Foo = {
        foo : "foo",
        bar : "bar",
        baz : function () {
        return true;
        }
};

Why is the following not allowed? Why is com.foobar.Foo not a constructor? Is it because Foo is not a function, but an object?

var baz = new com.foobar.Foo();

Since I cannot do the above, how would I create a new Foo?

If I want to extend Foo, I thought I would do this:

var bar = Object.create(com.foobar.Foo, {buz: {value: "neat"}});

.. but is bar a subtype of Foo or an instance of Foo? I'm leaning towards instance of Foo because the following prints 'undefine'

console.log(bar.prototype);

Dave
  • 776
  • 1
  • 10
  • 25

3 Answers3

2

You're correct, you can't do var baz = new com.foobar.Foo(); because Foo is an object, not a function.

Object.create is used to set the prototype of a variable (i.e. bar.prototype = Object.create(/*etc etc*/)). For more information, see the MDN page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

Using Object.create properly results in bar being another object with the prototype of Foo. This means that anything Foo has can be used on bar, eg bar.bar === 'bar' (if that makes sense). Changes to Foo will be reflected in bar, but not the other way around. It's not quite a subtype. (JS is weird, but it's delightfully so.)

For more on this, check out MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

SomeKittens
  • 38,868
  • 19
  • 114
  • 143
1

Javascript has no classes, only objects. When you create an object, it can also have a prototype, which is just another object that the created object will use to delegate calls to properties (or functions) it doesn't itself understand.

This works more or less like classic inheritance, since subclasses also delegate calls it doesn't understand to superclasses.

So, taking that lead, you'd like to make Foo a prototype for other objects you create; Foo would act somewhat like a superclass to the objects.

A handy function you already know about is the Object.create. You can use it to create a new object with a specific prototype, as you did:

var bar = Object.create(com.foobar.Foo, {buz: {value: "neat"}});

This means that bar will have a prototype of Foo and also will have an own property (i.e. not in the prototype) of buz.

Now, the prototype of bar, which points to Foo, can be found (at least in Chrome, since this is implementation specific) on the property __proto__. So this is true: bar.__proto__ === com.foobar.Foo.

Moving forward, if you want bar to also be a superclass prototype of another object, you'd do the same:

var subbar = Object.create(bar);

Makes sense? I'll later add more about Function, the property prototype and the new operator if you want....

Jordão
  • 55,340
  • 13
  • 112
  • 144
  • I only knew of *.prototype and not __proto__. Based on your answer, I looked up the difference between the two (http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript). Thanks for bringing this to my attention. – Dave Oct 26 '13 at 15:04
0

You are not able to instantiate Foo because it is an object, not a function. You can accomplish that by creating a function and using prototype to set the instance methods:

// constructor method
com.foobar.Foo = function() {
    this.foo = 'foo'
    this.bar = 'bar'
}

com.foobar.Foo.prototype.baz = function() {
    return true
}

Take a look at it running on jsfiddle: http://jsfiddle.net/DE7KZ/

Guilherme Sehn
  • 6,727
  • 18
  • 35