views:

57

answers:

1

Hello.

function A() {
    this.myProp = document.createElement("div"); }

function B(id) {
    this.myProp.id = id;
    document.body.appendChild(this.myProp); }

B.prototype = new A();

window.onload = function() {
    new B("hello");
    new B("goodbye"); }

What happens here is that I end up with one div with id "goodbye". What I would like is two divs with the specified ids.

I have been able to fix this problem by creating a method of "A" which creates the element.

How could I fix it without using the method?

+1  A: 

You have to call the constructor A() when creating a new B():

function A() {
    this.myProp = document.createElement("div");
}

function B(id) {
    A.call(this); // !!!
    this.myProp.id = id;
    document.body.appendChild(this.myProp);
}

If you want B instances to inherit from A.prototype, don't set B.prototype to an A instance, but use Object.create() - or a custom implementation for legacy browsers - to avoid a constructor invocation:

var clone = Object.create || (function() {
    function Dummy() {}
    return function(obj) {
        Dummy.prototype = obj;
        return new Dummy;
    };
})();

B.prototype = clone(A.prototype);
Christoph
Thanks for the helpful response. I don't quite understand why you use the Object.create() method. Would you be able to explain this?
willat8
@willat8: constructor functions are used to create and intialize instances, ie allocating resources the instance needs - but which are superfluous in the prototype object; in your case, an example for such a resource would be the `myProp` element; in other cases, the consequences can be more severe: for example, consider an object which registers itself as an event listener on initialization; would you want the prototype object of a sub-'class' to do this?
Christoph
@willat8: Or to use your code: consider a third class `C` which extends `B`; using `C.prototype = new B('foo');` would mean you'll append a `div` to `document.body` corresponding to the prototype object
Christoph
Instead of using an "A" instance could I set "B.prototype" to a reference of "A"? As in, B.prototype = A;
willat8
@willat8: you could use `B.prototype = A.prototype`, but this would mean that `A` and `B` instances would share the same prototype, ie it would be impossible to override methods
Christoph
addendum: you could still override methods by using so-called 'privileged methods', but I'd strongly advise against taking that route
Christoph