tags:

views:

117

answers:

3

Hi,

in many books and online tutorial there are examples on passing data to a super-class constructor via a borrowing method pattern:

var Parent = function(name)
{
    this.name = name;
    this.my_parent = "parent_property";
    this.go = function()
    {
        alert("GO")
    }   

}

var Child = function(name)
{  
    this.name = name;
    this.my_child = "child_property";

    Parent.call(this);

    alert(this.hasOwnProperty("go")) // HERE TRUE!!!
}

var ChildChild = function(name)
{
    this.name = name;
    this.su = function(){}
}

// PSEUDO CLASSICAL ECMA STANDARD
Child.prototype = new Parent("PARENT"); 
ChildChild.prototype = new Child("CHILD"); 
var c = new ChildChild("CHILDCHILD");

now my question is: is this correct? in that pattern the properties of the super-class are copied into THIS but in a OOP system I think that those properties must be in its super-class. Now BORROWING constructor is only another pattern to make a sort of inheritance so I could not use prototype and so all the chain superclass properties are into the last child class...but I don't think it's efficient.

So, at end, how can I pass data to a super-class without that pattern?

Thanks

A: 

By calling .call() you don't inherit in the classical sense of the word instead you tell Child to apply Parents prototype onto itself and thus Child.prototype has cloned properties and methods from Parent. This has no issues performance wise whatsoever though so abandoning prototype for efficiency reasons is not a valid reason.

If I can be honest I think enforcing OO paradigms onto javascript is the biggest mistake a javascript developer can make. Much like having to learn to deal with immutability in functional programming trying to make javascript behave like classical OO will only work against you in the long run.

It doesn't answer your question but there's tons of different ways to apply a super functionality to javascript none of which I can recommend though as there's no definitive version that doesn't come with a downside somewhere down the line.

Martijn Laarman
you wrote: ""Child to apply Parents prototype onto itself and thus Child.prototype has cloned properties and methods from Parent "".call or .apply simply use a function of another object passing as this the invoking object so I don't understand how prototype can work how you have said.
xdevel2000
A: 

JavaScript has no inherent support for building inheritance hierachies. The JavaScript way of doing type extensions would be to add properties from the 'parent class' to the 'child class', ie

function Parent(foo) {
    this.foo = foo;
}

Parent.prototype.sharedFoo = 'sharedFoo';

function Child(foo, bar) {
    // call the parent constructor
    Parent.call(this, foo);
    this.bar = bar;
}

Child.prototype.sharedBar = 'sharedBar';

// copy the properties of the parent class
for(var prop in Parent.prototype) {
    if(Parent.prototype.hasOwnProperty(prop))
        Child.prototype[prop] = Parent.prototype[prop];
}

It's also easily possible to add true prototypical inheritance, for example like this.

Via use of the clone() function, it's now possible to let the prototype object of the 'child class' inherit from the prototype object of the 'base class':

function Parent(foo) {
    this.foo = foo;
}

Parent.prototype.sharedFoo = 'sharedFoo';

function Child(foo, bar) {
    // call the parent constructor
    Parent.call(this, foo);
    this.bar = bar;
}

// inherit from the parent class
Child.prototype = clone(Parent.prototype);

Child.prototype.sharedBar = 'sharedBar';
Christoph
in JS you can do inheritance in many ways...that you have written is one on many... for ECMA the inheritance should be done via a prototype (pseudo-classical) and I don't agree with your assertion "JavaScript has no inherent support for building inheritance hierachies". I think it has how ECMA says.
xdevel2000
@xdevel2000: JS has no inherent support for hierachies (inherent meaning syntactical or with built-in objects); if you want it, you have to supply it yourself (see the clone() function or class based inheritance: http://mercurial.intuxication.org/hg/js-hacks-docs/raw-file/tip/class-en.html )
Christoph
@xdevel2000: the 'JavaScript-way' of extension is aggregation, not inheritance, but as I already said, the language is powerful enough to support other paradigms, but it doesn't mean that it was designed to accomodate them
Christoph
+1  A: 

JavaScript is a prototype based, functional language that pretends to be the cousin of Java.

Here is a few key things about JavasSript:

  • Everything is an Object, including Functions
  • Object is more like Hash, it is a collection of key value pairs
  • prototype itself is Object as well

To answer your first question about performance of "borrowing" prototype:

Typically, a JavaScript class contains a collection of [name, function object] pairs. When you borrow the prototype of the parent class, you basically copy the values of the parent prototype object into child class's prototype object.

The copy is by reference, when the function is copied, the function code is not duplicated, only the reference is copied. This is similar to function pointers in C language.

Thus the only performance hit is the duplication of the prototype object, which takes very little memory.

To answer your second question of how to pass data to Parent Class in a clean way:

There are many libraries out there that has some OOP style inheritance already built in. You can roll your own as well, but that would not be trivial.

I recommend a framework called Joose.

  • It supports classes, inheritance, mixins, traits, method modifiers and more.
  • Stable and used in production environments.
  • Elegant, and will save you a lot of key strokes

Using Joose, parent constructors can be overridden or augmented, and SUPER() or INNER() methods will be provided to access the original constructor, or the subclass constructor.

Aaron Qian
Also mootools (http://mootools.net), which stands for More Object Oriented Tools, is a great javascript OOP framework.
tj111